From f607a99127cc9e8dfc3f716f977e6c1bfb6f7c2d Mon Sep 17 00:00:00 2001 From: Martin Thierer Date: Tue, 20 Jul 2021 18:55:00 +0200 Subject: [PATCH 001/454] 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; } From 34ae21319e2e5c34d1e210e36231f695581ae05a Mon Sep 17 00:00:00 2001 From: tobozo Date: Wed, 2 Mar 2022 15:00:07 +0100 Subject: [PATCH 002/454] added Absolute Mouse report struct --- src/class/hid/hid.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/class/hid/hid.h b/src/class/hid/hid.h index 940454bd9..667ee79aa 100644 --- a/src/class/hid/hid.h +++ b/src/class/hid/hid.h @@ -300,6 +300,20 @@ typedef struct TU_ATTR_PACKED int8_t pan; // using AC Pan } hid_mouse_report_t; + +// Absolute Mouse: same as the Standard (relative) Mouse Report but +// with int16_t instead of int8_t for X and Y coordinates. +typedef struct TU_ATTR_PACKED +{ + uint8_t buttons; /**< buttons mask for currently pressed buttons in the mouse. */ + int16_t x; /**< Current x position of the mouse. */ + int16_t y; /**< Current y position of the mouse. */ + int8_t wheel; /**< Current delta wheel movement on the mouse. */ + int8_t pan; // using AC Pan +} abs_mouse_report_t; + + + /// Standard Mouse Buttons Bitmap typedef enum { From 8c79b8924eabf441f40a8ce3cab8828688575b6d Mon Sep 17 00:00:00 2001 From: tobozo Date: Wed, 2 Mar 2022 15:01:18 +0100 Subject: [PATCH 003/454] added Absolute Mouse descriptor template --- src/class/hid/hid_device.h | 49 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h index 078b67349..547a78f4f 100644 --- a/src/class/hid/hid_device.h +++ b/src/class/hid/hid_device.h @@ -266,6 +266,55 @@ static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y HID_COLLECTION_END , \ HID_COLLECTION_END \ +// Absolute Mouse Report Descriptor Template +#define TUD_HID_REPORT_DESC_ABSMOUSE(...) \ + HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\ + HID_USAGE ( HID_USAGE_DESKTOP_MOUSE ) ,\ + HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\ + /* Report ID if any */\ + __VA_ARGS__ \ + HID_USAGE ( HID_USAGE_DESKTOP_POINTER ) ,\ + HID_COLLECTION ( HID_COLLECTION_PHYSICAL ) ,\ + HID_USAGE_PAGE ( HID_USAGE_PAGE_BUTTON ) ,\ + HID_USAGE_MIN ( 1 ) ,\ + HID_USAGE_MAX ( 5 ) ,\ + HID_LOGICAL_MIN ( 0 ) ,\ + HID_LOGICAL_MAX ( 1 ) ,\ + /* Left, Right, Middle, Backward, Forward buttons */ \ + HID_REPORT_COUNT( 5 ) ,\ + HID_REPORT_SIZE ( 1 ) ,\ + HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\ + /* 3 bit padding */ \ + HID_REPORT_COUNT( 1 ) ,\ + HID_REPORT_SIZE ( 3 ) ,\ + HID_INPUT ( HID_CONSTANT ) ,\ + HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\ + /* X, Y absolute position [0, 32767] */ \ + HID_USAGE ( HID_USAGE_DESKTOP_X ) ,\ + HID_USAGE ( HID_USAGE_DESKTOP_Y ) ,\ + HID_LOGICAL_MIN ( 0x00 ) ,\ + HID_LOGICAL_MAX_N( 0x7FFF, 2 ) ,\ + HID_REPORT_SIZE ( 16 ) ,\ + HID_REPORT_COUNT ( 2 ) ,\ + HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\ + /* Vertical wheel scroll [-127, 127] */ \ + HID_USAGE ( HID_USAGE_DESKTOP_WHEEL ) ,\ + HID_LOGICAL_MIN ( 0x81 ) ,\ + HID_LOGICAL_MAX ( 0x7f ) ,\ + HID_REPORT_COUNT( 1 ) ,\ + HID_REPORT_SIZE ( 8 ) ,\ + HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ) ,\ + HID_USAGE_PAGE ( HID_USAGE_PAGE_CONSUMER ), \ + /* Horizontal wheel scroll [-127, 127] */ \ + HID_USAGE_N ( HID_USAGE_CONSUMER_AC_PAN, 2 ), \ + HID_LOGICAL_MIN ( 0x81 ), \ + HID_LOGICAL_MAX ( 0x7f ), \ + HID_REPORT_COUNT( 1 ), \ + HID_REPORT_SIZE ( 8 ), \ + HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ), \ + HID_COLLECTION_END , \ + HID_COLLECTION_END \ + // Consumer Control Report Descriptor Template #define TUD_HID_REPORT_DESC_CONSUMER(...) \ HID_USAGE_PAGE ( HID_USAGE_PAGE_CONSUMER ) ,\ From 9526a0ff736ccc4c8a9791a8467d6a6de82c0c45 Mon Sep 17 00:00:00 2001 From: tobozo Date: Wed, 2 Mar 2022 16:56:59 +0100 Subject: [PATCH 004/454] stick to struct naming convention --- 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 667ee79aa..98c2ee0de 100644 --- a/src/class/hid/hid.h +++ b/src/class/hid/hid.h @@ -310,7 +310,7 @@ typedef struct TU_ATTR_PACKED int16_t y; /**< Current y position of the mouse. */ int8_t wheel; /**< Current delta wheel movement on the mouse. */ int8_t pan; // using AC Pan -} abs_mouse_report_t; +} hid_abs_mouse_report_t; From f931983469bf375eec9503b99e021b9b633bf23f Mon Sep 17 00:00:00 2001 From: Mark K Cowan Date: Sun, 23 Oct 2022 02:55:28 +0300 Subject: [PATCH 005/454] UAC2 supports interrupt-endpoint for providing control-change notifications to the host --- src/class/audio/audio_device.c | 58 ++++++++++++++++++++++++++++++++-- src/class/audio/audio_device.h | 46 ++++++++++++++++++++++++--- 2 files changed, 96 insertions(+), 8 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index a65d605b7..05339f9ce 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -341,7 +341,7 @@ typedef struct // Audio control interrupt buffer - no FIFO - 6 Bytes according to UAC 2 specification (p. 74) #if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN - CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t ep_int_ctr_buf[CFG_TUD_AUDIO_INT_CTR_EP_IN_SW_BUFFER_SIZE]; + CFG_TUSB_MEM_ALIGN uint8_t ep_int_ctr_buf[CFG_TUD_AUDIO_INT_CTR_EP_IN_SW_BUFFER_SIZE]; #endif // Decoding parameters - parameters are set when alternate AS interface is set by host @@ -464,7 +464,7 @@ bool tud_audio_n_mounted(uint8_t func_id) if (audio->ep_in == 0) return false; #endif -#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN +#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP if (audio->ep_int_ctr == 0) return false; #endif @@ -813,11 +813,13 @@ tu_fifo_t* tud_audio_n_get_tx_support_ff(uint8_t func_id, uint8_t ff_idx) #endif -#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN +#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP // If no interrupt transmit is pending bytes get written into buffer and a transmit is scheduled - once transmit completed tud_audio_int_ctr_done_cb() is called in inform user uint16_t tud_audio_int_ctr_n_write(uint8_t func_id, uint8_t const* buffer, uint16_t len) { + TU_VERIFY(_audiod_fct[func_id].ep_int_ctr != 0); + TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL); // We write directly into the EP's buffer - abort if previous transfer not complete @@ -1079,6 +1081,52 @@ static inline bool audiod_fb_send(uint8_t rhport, audiod_function_t *audio) } #endif +#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP +static bool set_int_ctr_number(audiod_function_t *audio) +{ + + uint8_t const *p_desc = audio->p_desc; + // Get pointer at end + 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) + { + // Find correct interface + if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE && ((tusb_desc_interface_t const * )p_desc)->bInterfaceNumber == 0 && ((tusb_desc_interface_t const * )p_desc)->bAlternateSetting == 0) + { + + uint8_t foundEPs = 0, nEps = ((tusb_desc_interface_t const * )p_desc)->bNumEndpoints; + while (foundEPs < nEps && p_desc < p_desc_end) + { + // found :n endpoint + if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) + { + tusb_desc_endpoint_t const* desc_ep = (tusb_desc_endpoint_t const *) p_desc; + + uint8_t const ep_addr = desc_ep->bEndpointAddress; + + if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN && desc_ep->bmAttributes.xfer == 0x03) // Check if usage is interrupt EP + { + audio->ep_int_ctr = ep_addr; + TU_ASSERT(usbd_edpt_open(audio->rhport, desc_ep)); + } + + foundEPs += 1; + } + p_desc = tu_desc_next(p_desc); + } + break; + } + p_desc = tu_desc_next(p_desc); + } + + return true; + +} +#endif + //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ @@ -1484,6 +1532,10 @@ uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin // This is all we need so far - the EPs are setup by a later set_interface request (as per UAC2 specification) uint16_t drv_len = _audiod_fct[i].desc_length - TUD_AUDIO_DESC_IAD_LEN; // - TUD_AUDIO_DESC_IAD_LEN since tinyUSB already handles the IAD descriptor +#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP + TU_ASSERT(set_int_ctr_number(&_audiod_fct[i])); +#endif + return drv_len; } diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index 0ef100fa4..0c394d235 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -191,9 +191,19 @@ #define CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION 0 // 0 or 1 #endif +// Enable/disable interrupt EP (required for notifying host of control changes) +#ifndef CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP +#define CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP 0 // Feedback - 0 or 1 +#endif + // Audio interrupt control EP size - disabled if 0 #ifndef CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN -#define CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN 0 // Audio interrupt control - if required - 6 Bytes according to UAC 2 specification (p. 74) +// Audio interrupt control - if required - 6 Bytes according to UAC 2 specification (p. 74) +#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP +#define CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN 6 +#else +#define CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN 0 +#endif #endif #ifndef CFG_TUD_AUDIO_INT_CTR_EP_IN_SW_BUFFER_SIZE @@ -388,7 +398,7 @@ uint16_t tud_audio_n_write_support_ff (uint8_t func_id, uint8_t ff_i tu_fifo_t* tud_audio_n_get_tx_support_ff (uint8_t func_id, uint8_t ff_idx); #endif -#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN +#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP uint16_t tud_audio_int_ctr_n_write (uint8_t func_id, uint8_t const* buffer, uint16_t len); #endif @@ -431,7 +441,7 @@ static inline tu_fifo_t* tud_audio_get_tx_support_ff (uint8_t ff_idx); // INT CTR API -#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN +#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP static inline uint16_t tud_audio_int_ctr_write (uint8_t const* buffer, uint16_t len); #endif @@ -531,7 +541,33 @@ TU_ATTR_WEAK TU_ATTR_FAST_FUNC void tud_audio_feedback_interval_isr(uint8_t func #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP -#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN +#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP +// UAC2 §9.6 +// Structure of "interrupt data message" +typedef struct TU_ATTR_PACKED +{ + uint8_t bInfo; + uint8_t bAttribute; + union TU_ATTR_PACKED + { + uint16_t wValue; + struct TU_ATTR_PACKED + { + uint8_t wValue_cn_or_mcn; + uint8_t wValue_cs; + }; + }; + union TU_ATTR_PACKED + { + uint16_t wIndex; + struct TU_ATTR_PACKED + { + uint8_t wIndex_ep_or_int; + uint8_t wIndex_entity_id; + }; + }; +} audio_status_update_t; + TU_ATTR_WEAK bool tud_audio_int_ctr_done_cb(uint8_t rhport, uint16_t n_bytes_copied); #endif @@ -663,7 +699,7 @@ static inline tu_fifo_t* tud_audio_get_tx_support_ff(uint8_t ff_idx) #endif -#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN +#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP static inline uint16_t tud_audio_int_ctr_write(uint8_t const* buffer, uint16_t len) { return tud_audio_int_ctr_n_write(0, buffer, len); From 025d3477e81e07ddc2db78193e8957cdb1050516 Mon Sep 17 00:00:00 2001 From: Mark K Cowan Date: Mon, 24 Oct 2022 20:41:09 +0300 Subject: [PATCH 006/454] fixed spec reference --- src/class/audio/audio_device.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index 0c394d235..92a1e6585 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -542,8 +542,7 @@ TU_ATTR_WEAK TU_ATTR_FAST_FUNC void tud_audio_feedback_interval_isr(uint8_t func #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP #if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP -// UAC2 §9.6 -// Structure of "interrupt data message" +// UAC2 §6.1 "interrupt data message" typedef struct TU_ATTR_PACKED { uint8_t bInfo; From 15ed45e1a33210c5e949801a77aabd544fa170ed Mon Sep 17 00:00:00 2001 From: Mark K Cowan Date: Wed, 26 Oct 2022 21:40:30 +0300 Subject: [PATCH 007/454] clean up descriptor search for interrupt endpoint --- src/class/audio/audio_device.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 05339f9ce..efa06cf70 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -1090,40 +1090,36 @@ static bool set_int_ctr_number(audiod_function_t *audio) 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) + bool found = false; + while (!found && p_desc < p_desc_end) { - // Find correct interface - if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE && ((tusb_desc_interface_t const * )p_desc)->bInterfaceNumber == 0 && ((tusb_desc_interface_t const * )p_desc)->bAlternateSetting == 0) + // For each interface/alternate + if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE) { - uint8_t foundEPs = 0, nEps = ((tusb_desc_interface_t const * )p_desc)->bNumEndpoints; - while (foundEPs < nEps && p_desc < p_desc_end) + while (!found && foundEPs < nEps && p_desc < p_desc_end) { - // found :n endpoint + // For each endpoint if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) { tusb_desc_endpoint_t const* desc_ep = (tusb_desc_endpoint_t const *) p_desc; - uint8_t const ep_addr = desc_ep->bEndpointAddress; - + // If endpoint is input-direction and interrupt-type if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN && desc_ep->bmAttributes.xfer == 0x03) // Check if usage is interrupt EP { + // Store endpoint number and open endpoint audio->ep_int_ctr = ep_addr; TU_ASSERT(usbd_edpt_open(audio->rhport, desc_ep)); + found = true; } - foundEPs += 1; } p_desc = tu_desc_next(p_desc); } - break; } p_desc = tu_desc_next(p_desc); } - - return true; - + return found; } #endif From 9673d20901dd5419c82ccc14dd2fd300ca0fa8c4 Mon Sep 17 00:00:00 2001 From: Mark K Cowan Date: Wed, 26 Oct 2022 21:43:27 +0300 Subject: [PATCH 008/454] PanRe refactor applied: s{_int_ctr_}{_int_}g; s{_INT_CTR_}{_INT_}g; --- src/class/audio/audio_device.c | 38 +++++++++++++++++----------------- src/class/audio/audio_device.h | 20 +++++++++--------- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index efa06cf70..4681e1ddb 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -283,8 +283,8 @@ typedef struct #endif -#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN - uint8_t ep_int_ctr; // Audio control interrupt EP. +#if CFG_TUD_AUDIO_INT_EPSIZE_IN + uint8_t ep_int; // Audio control interrupt EP. #endif /*------------- From this point, data is not cleared by bus reset -------------*/ @@ -340,8 +340,8 @@ typedef struct #endif // Audio control interrupt buffer - no FIFO - 6 Bytes according to UAC 2 specification (p. 74) -#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN - CFG_TUSB_MEM_ALIGN uint8_t ep_int_ctr_buf[CFG_TUD_AUDIO_INT_CTR_EP_IN_SW_BUFFER_SIZE]; +#if CFG_TUD_AUDIO_INT_EPSIZE_IN + CFG_TUSB_MEM_ALIGN uint8_t ep_int_buf[CFG_TUD_AUDIO_INT_EP_IN_SW_BUFFER_SIZE]; #endif // Decoding parameters - parameters are set when alternate AS interface is set by host @@ -465,7 +465,7 @@ bool tud_audio_n_mounted(uint8_t func_id) #endif #if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP - if (audio->ep_int_ctr == 0) return false; + if (audio->ep_int == 0) return false; #endif #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP @@ -815,23 +815,23 @@ tu_fifo_t* tud_audio_n_get_tx_support_ff(uint8_t func_id, uint8_t ff_idx) #if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP -// If no interrupt transmit is pending bytes get written into buffer and a transmit is scheduled - once transmit completed tud_audio_int_ctr_done_cb() is called in inform user -uint16_t tud_audio_int_ctr_n_write(uint8_t func_id, uint8_t const* buffer, uint16_t len) +// If no interrupt transmit is pending bytes get written into buffer and a transmit is scheduled - once transmit completed tud_audio_int_done_cb() is called in inform user +uint16_t tud_audio_int_n_write(uint8_t func_id, uint8_t const* buffer, uint16_t len) { - TU_VERIFY(_audiod_fct[func_id].ep_int_ctr != 0); + TU_VERIFY(_audiod_fct[func_id].ep_int != 0); TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL); // We write directly into the EP's buffer - abort if previous transfer not complete - TU_VERIFY(!usbd_edpt_busy(_audiod_fct[func_id].rhport, _audiod_fct[func_id].ep_int_ctr)); + TU_VERIFY(!usbd_edpt_busy(_audiod_fct[func_id].rhport, _audiod_fct[func_id].ep_int)); // Check length - TU_VERIFY(len <= CFG_TUD_AUDIO_INT_CTR_EP_IN_SW_BUFFER_SIZE); + TU_VERIFY(len <= CFG_TUD_AUDIO_INT_EP_IN_SW_BUFFER_SIZE); - memcpy(_audiod_fct[func_id].ep_int_ctr_buf, buffer, len); + memcpy(_audiod_fct[func_id].ep_int_buf, buffer, len); // Schedule transmit - TU_VERIFY(usbd_edpt_xfer(_audiod_fct[func_id].rhport, _audiod_fct[func_id].ep_int_ctr, _audiod_fct[func_id].ep_int_ctr_buf, len)); + TU_VERIFY(usbd_edpt_xfer(_audiod_fct[func_id].rhport, _audiod_fct[func_id].ep_int, _audiod_fct[func_id].ep_int_buf, len)); return true; } @@ -1082,7 +1082,7 @@ static inline bool audiod_fb_send(uint8_t rhport, audiod_function_t *audio) #endif #if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP -static bool set_int_ctr_number(audiod_function_t *audio) +static bool set_int_number(audiod_function_t *audio) { uint8_t const *p_desc = audio->p_desc; @@ -1108,7 +1108,7 @@ static bool set_int_ctr_number(audiod_function_t *audio) if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN && desc_ep->bmAttributes.xfer == 0x03) // Check if usage is interrupt EP { // Store endpoint number and open endpoint - audio->ep_int_ctr = ep_addr; + audio->ep_int = ep_addr; TU_ASSERT(usbd_edpt_open(audio->rhport, desc_ep)); found = true; } @@ -1485,7 +1485,7 @@ uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin // Verify interrupt control EP is enabled if demanded by descriptor - this should be best some static check however - this check can be omitted if (itf_desc->bNumEndpoints == 1) // 0 or 1 EPs are allowed { - TU_VERIFY(CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN > 0); + TU_VERIFY(CFG_TUD_AUDIO_INT_EPSIZE_IN > 0); } // Alternate setting MUST be zero - this check can be omitted @@ -1529,7 +1529,7 @@ uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin uint16_t drv_len = _audiod_fct[i].desc_length - TUD_AUDIO_DESC_IAD_LEN; // - TUD_AUDIO_DESC_IAD_LEN since tinyUSB already handles the IAD descriptor #if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP - TU_ASSERT(set_int_ctr_number(&_audiod_fct[i])); + TU_ASSERT(set_int_number(&_audiod_fct[i])); #endif return drv_len; @@ -2030,10 +2030,10 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 { audiod_function_t* audio = &_audiod_fct[func_id]; -#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN +#if CFG_TUD_AUDIO_INT_EPSIZE_IN // Data transmission of control interrupt finished - if (audio->ep_int_ctr == ep_addr) + if (audio->ep_int == ep_addr) { // According to USB2 specification, maximum payload of interrupt EP is 8 bytes on low speed, 64 bytes on full speed, and 1024 bytes on high speed (but only if an alternate interface other than 0 is used - see specification p. 49) // In case there is nothing to send we have to return a NAK - this is taken care of by PHY ??? @@ -2042,7 +2042,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_ctr_done_cb) TU_VERIFY(tud_audio_int_ctr_done_cb(rhport, (uint16_t) xferred_bytes)); + if (tud_audio_int_done_cb) TU_VERIFY(tud_audio_int_done_cb(rhport, (uint16_t) xferred_bytes)); } #endif diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index 92a1e6585..2e39e6049 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -197,17 +197,17 @@ #endif // Audio interrupt control EP size - disabled if 0 -#ifndef CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN +#ifndef CFG_TUD_AUDIO_INT_EPSIZE_IN // Audio interrupt control - if required - 6 Bytes according to UAC 2 specification (p. 74) #if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP -#define CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN 6 +#define CFG_TUD_AUDIO_INT_EPSIZE_IN 6 #else -#define CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN 0 +#define CFG_TUD_AUDIO_INT_EPSIZE_IN 0 #endif #endif -#ifndef CFG_TUD_AUDIO_INT_CTR_EP_IN_SW_BUFFER_SIZE -#define CFG_TUD_AUDIO_INT_CTR_EP_IN_SW_BUFFER_SIZE 6 // Buffer size of audio control interrupt EP - 6 Bytes according to UAC 2 specification (p. 74) +#ifndef CFG_TUD_AUDIO_INT_EP_IN_SW_BUFFER_SIZE +#define CFG_TUD_AUDIO_INT_EP_IN_SW_BUFFER_SIZE 6 // Buffer size of audio control interrupt EP - 6 Bytes according to UAC 2 specification (p. 74) #endif // Use software encoding/decoding @@ -399,7 +399,7 @@ tu_fifo_t* tud_audio_n_get_tx_support_ff (uint8_t func_id, uint8_t ff_i #endif #if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP -uint16_t tud_audio_int_ctr_n_write (uint8_t func_id, uint8_t const* buffer, uint16_t len); +uint16_t tud_audio_int_n_write (uint8_t func_id, uint8_t const* buffer, uint16_t len); #endif //--------------------------------------------------------------------+ @@ -442,7 +442,7 @@ static inline tu_fifo_t* tud_audio_get_tx_support_ff (uint8_t ff_idx); // INT CTR API #if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP -static inline uint16_t tud_audio_int_ctr_write (uint8_t const* buffer, uint16_t len); +static inline uint16_t tud_audio_int_write (uint8_t const* buffer, uint16_t len); #endif // Buffer control EP data and schedule a transmit @@ -567,7 +567,7 @@ typedef struct TU_ATTR_PACKED }; } audio_status_update_t; -TU_ATTR_WEAK bool tud_audio_int_ctr_done_cb(uint8_t rhport, uint16_t n_bytes_copied); +TU_ATTR_WEAK bool tud_audio_int_done_cb(uint8_t rhport, uint16_t n_bytes_copied); #endif // Invoked when audio set interface request received @@ -699,9 +699,9 @@ static inline tu_fifo_t* tud_audio_get_tx_support_ff(uint8_t ff_idx) #endif #if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP -static inline uint16_t tud_audio_int_ctr_write(uint8_t const* buffer, uint16_t len) +static inline uint16_t tud_audio_int_write(uint8_t const* buffer, uint16_t len) { - return tud_audio_int_ctr_n_write(0, buffer, len); + return tud_audio_int_n_write(0, buffer, len); } #endif From 4c510c12b1d0a0bfb0726c0100ff22cd892aa1e8 Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Mon, 27 Feb 2023 09:54:45 +0100 Subject: [PATCH 009/454] synopsys/dwc2: fix SOF interrupt handling SOF is not a flag of the GOTGINT register but of the GINTSTS register. Therefore the flag must be written in the GINTSTS register instead of the GOTGINT register to clear the interrupt. --- src/portable/synopsys/dwc2/dcd_dwc2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index c6132a1f5..7d4f31c48 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -1288,7 +1288,7 @@ void dcd_int_handler(uint8_t rhport) if(int_status & GINTSTS_SOF) { - dwc2->gotgint = GINTSTS_SOF; + dwc2->gintsts = GINTSTS_SOF; if (_sof_en) { From a77aaf7f9e8a86c904d0bf6e8994288f45b3b410 Mon Sep 17 00:00:00 2001 From: tobozo Date: Thu, 30 Mar 2023 21:57:06 +0200 Subject: [PATCH 010/454] Added helpers for abs_mouse_report --- src/class/hid/hid_device.c | 13 +++++++++++++ src/class/hid/hid_device.h | 12 +++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 9240fe2ca..7e28b2c94 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -146,6 +146,19 @@ bool tud_hid_n_mouse_report(uint8_t instance, uint8_t report_id, 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) +{ + hid_abs_mouse_report_t report = + { + .buttons = buttons, + .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 = diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h index cb794e964..40755afed 100644 --- a/src/class/hid/hid_device.h +++ b/src/class/hid/hid_device.h @@ -72,6 +72,16 @@ bool tud_hid_n_keyboard_report(uint8_t instance, uint8_t report_id, uint8_t modi // use template layout report as defined by hid_mouse_report_t 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); +// ABSOLUTE MOUSE: convenient helper to send absolute mouse report if application +// 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); @@ -314,7 +324,7 @@ static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ), \ HID_COLLECTION_END , \ HID_COLLECTION_END \ - + // Consumer Control Report Descriptor Template #define TUD_HID_REPORT_DESC_CONSUMER(...) \ HID_USAGE_PAGE ( HID_USAGE_PAGE_CONSUMER ) ,\ From 805ebb39249a7b96092a9c59d244152bc343d898 Mon Sep 17 00:00:00 2001 From: tobozo Date: Thu, 30 Mar 2023 22:01:36 +0200 Subject: [PATCH 011/454] remove trailing space (satisfy pre-commit flow) --- src/class/hid/hid.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/class/hid/hid.h b/src/class/hid/hid.h index 3e238966f..fcaab7a50 100644 --- a/src/class/hid/hid.h +++ b/src/class/hid/hid.h @@ -312,8 +312,7 @@ typedef struct TU_ATTR_PACKED int8_t pan; // using AC Pan } hid_abs_mouse_report_t; - - + /// Standard Mouse Buttons Bitmap typedef enum { From 5ade91780578bca10bae048a58fed4b788b553d1 Mon Sep 17 00:00:00 2001 From: Michiel van Leeuwen Date: Fri, 28 Apr 2023 11:26:26 +0200 Subject: [PATCH 012/454] dwc2: configure fifo size to be twice the max_size This is needed in order to always be able to fit a packet in the fifo. Writing to the fifo is done from an interrupts that fires when the fifo is half-empty, so the fifo must be twice the packet size. --- src/portable/synopsys/dwc2/dcd_dwc2.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index c6132a1f5..bcd584953 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -534,6 +534,9 @@ void dcd_init (uint8_t rhport) int_mask = dwc2->gotgint; dwc2->gotgint |= int_mask; + // Configure TX FIFO to set the TX FIFO empty interrupt when half-empty + dwc2->gahbcfg &= ~GAHBCFG_TXFELVL; + // Required as part of core initialization. // TODO: How should mode mismatch be handled? It will cause // the core to stop working/require reset. @@ -645,7 +648,10 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) xfer->max_size = tu_edpt_packet_size(desc_edpt); xfer->interval = desc_edpt->bInterval; - uint16_t const fifo_size = tu_div_ceil(xfer->max_size, 4); + // The fifo-empty interrupt fires when the interrupt is half empty. In order + // to be able to write a packet at that point, the fifo must be twice the + // max_size. + uint16_t const fifo_size = tu_div_ceil(xfer->max_size * 2, 4); if(dir == TUSB_DIR_OUT) { From 678edbe20320fe4d17437a9175ec8ff88f752ecb Mon Sep 17 00:00:00 2001 From: Michiel van Leeuwen Date: Fri, 28 Apr 2023 11:39:39 +0200 Subject: [PATCH 013/454] Check correct interrupt flag Fixes #1737 --- src/portable/synopsys/dwc2/dcd_dwc2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index bcd584953..d84014789 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -1322,7 +1322,7 @@ void dcd_int_handler(uint8_t rhport) do { handle_rxflvl_irq(rhport); - } while(dwc2->gotgint & GINTSTS_RXFLVL); + } while(dwc2->gintsts & GINTSTS_RXFLVL); // Manage RX FIFO size if (_out_ep_closed) From 75cf8e21a7e525eb24b7fd34fe5859cba331fcc2 Mon Sep 17 00:00:00 2001 From: Michiel van Leeuwen Date: Thu, 4 May 2023 10:02:42 +0200 Subject: [PATCH 014/454] Use double-sized fifo only for IN endpoints --- src/portable/synopsys/dwc2/dcd_dwc2.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index d84014789..c3d3ae085 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -648,10 +648,7 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) xfer->max_size = tu_edpt_packet_size(desc_edpt); xfer->interval = desc_edpt->bInterval; - // The fifo-empty interrupt fires when the interrupt is half empty. In order - // to be able to write a packet at that point, the fifo must be twice the - // max_size. - uint16_t const fifo_size = tu_div_ceil(xfer->max_size * 2, 4); + uint16_t fifo_size = tu_div_ceil(xfer->max_size, 4); if(dir == TUSB_DIR_OUT) { @@ -697,6 +694,11 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) // In FIFO is allocated by following rules: // - IN EP 1 gets FIFO 1, IN EP "n" gets FIFO "n". + // The fifo-empty interrupt fires when the interrupt is half empty. In order + // to be able to write a packet at that point, the fifo must be twice the + // max_size. + fifo_size = 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); From cba327fc384ae730287b0ab620d1f7ef50b0da3b Mon Sep 17 00:00:00 2001 From: mndza Date: Fri, 30 Jun 2023 11:20:58 +0200 Subject: [PATCH 015/454] 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 | 418 ++++++++++++++++++++++++++--------------- 1 file changed, 268 insertions(+), 150 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 +// 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; - // 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; + 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 const uint32_t * rx_fifo = (volatile const uint32_t *) app_buf; + // current buffer of fifo + uint8_t* ff_buf = f->buffer + (wr_ptr * f->item_size); - uint8_t remrem = (uint8_t) tu_min16(wrap_bytes, 4-rem); - wrap_bytes -= remrem; + // 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 - uint32_t tmp32 = *rx_fifo; - uint8_t * src_u8 = ((uint8_t *) &tmp32); + // 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; - // Write 1-3 bytes before wrapped boundary - while(rem--) *ff_buf++ = *src_u8++; + // 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; - // 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 - } + uint8_t remrem = (uint8_t) tu_min16(wrap_bytes, 4-rem); + wrap_bytes -= remrem; - // Write data wrapped part - if (wrap_bytes > 0) _ff_push_const_addr(ff_buf, app_buf, wrap_bytes); - } - break; + 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; - - 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 - - // 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; - - // 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; - - uint8_t remrem = (uint8_t) tu_min16(wrap_bytes, 4-rem); - wrap_bytes -= remrem; - - uint32_t tmp32=0; - uint8_t * dst_u8 = (uint8_t *)&tmp32; - - // 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++; - - *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); - } - break; - - default: break; + // Read data wrapped part + memcpy((uint8_t*) app_buf + lin_bytes, f->buffer, wrap_bytes); } } +// 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 + + 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 + (rd_ptr * f->item_size); + + if ( n <= lin_count ) + { + // Linear only + _ff_pull_const_addr(app_buf, ff_buf, n*f->item_size); + } + else + { + // Wrap around case + + // 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; + + // 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; + + uint8_t remrem = (uint8_t) tu_min16(wrap_bytes, 4-rem); + wrap_bytes -= remrem; + + uint32_t tmp32=0; + uint8_t * dst_u8 = (uint8_t *)&tmp32; + + // 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++; + + *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,7 @@ 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; - }else - { - // TODO should read from hw fifo to discard data, however reading an odd number could - // accidentally discard data. - } - + 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 @@ -534,7 +557,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(f, buf8, n, wr_ptr); // Advance index f->wr_idx = advance_index(f->depth, wr_idx, n); @@ -547,13 +570,108 @@ 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_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 + 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) + { + // 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 + { + // 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_const_addr(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_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, copy_mode); + 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_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); } /******************************************************************************/ From e2f28bc134446dc081766055171ca427afd4f564 Mon Sep 17 00:00:00 2001 From: emb4fun Date: Sun, 23 Jul 2023 10:53:22 +0200 Subject: [PATCH 016/454] Added support for the NXP K64 series --- hw/bsp/board_mcu.h | 2 +- src/common/tusb_mcu.h | 2 +- src/portable/nxp/khci/dcd_khci.c | 14 ++++++++++++++ src/tusb_option.h | 1 + 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/hw/bsp/board_mcu.h b/hw/bsp/board_mcu.h index e5d2bb608..3928435f0 100644 --- a/hw/bsp/board_mcu.h +++ b/hw/bsp/board_mcu.h @@ -47,7 +47,7 @@ #elif TU_CHECK_MCU(OPT_MCU_LPC51UXX, OPT_MCU_LPC54XXX, OPT_MCU_LPC55XX, OPT_MCU_MCXN9) #include "fsl_device_registers.h" -#elif TU_CHECK_MCU(OPT_MCU_KINETIS_KL, OPT_MCU_KINETIS_K32L) +#elif TU_CHECK_MCU(OPT_MCU_KINETIS_KL, OPT_MCU_KINETIS_K32L, OPT_MCU_KINETIS_K64) #include "fsl_device_registers.h" #elif CFG_TUSB_MCU == OPT_MCU_NRF5X diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 9f3be78fd..4a0c5acef 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -97,7 +97,7 @@ #define TUP_DCD_ENDPOINT_MAX 8 #define TUP_RHPORT_HIGHSPEED 1 -#elif TU_CHECK_MCU(OPT_MCU_KINETIS_KL, OPT_MCU_KINETIS_K32L) +#elif TU_CHECK_MCU(OPT_MCU_KINETIS_KL, OPT_MCU_KINETIS_K32L, OPT_MCU_KINETIS_K64) #define TUP_USBIP_CHIPIDEA_FS #define TUP_USBIP_CHIPIDEA_FS_KINETIS #define TUP_DCD_ENDPOINT_MAX 16 diff --git a/src/portable/nxp/khci/dcd_khci.c b/src/portable/nxp/khci/dcd_khci.c index 52f4145f2..d957338ad 100644 --- a/src/portable/nxp/khci/dcd_khci.c +++ b/src/portable/nxp/khci/dcd_khci.c @@ -269,9 +269,23 @@ void dcd_init(uint8_t rhport) { (void) rhport; +#if (CFG_TUSB_MCU == OPT_MCU_KINETIS_K64) + uint32_t clk_recover_irc_en; + uint32_t clk_recover_ctrl; + + clk_recover_irc_en = KHCI->CLK_RECOVER_IRC_EN; + clk_recover_ctrl = KHCI->CLK_RECOVER_CTRL; + KHCI->USBTRC0 |= USB_USBTRC0_USBRESET_MASK; while (KHCI->USBTRC0 & USB_USBTRC0_USBRESET_MASK); + KHCI->CLK_RECOVER_IRC_EN = clk_recover_irc_en; + KHCI->CLK_RECOVER_CTRL |= clk_recover_ctrl; +#else + KHCI->USBTRC0 |= USB_USBTRC0_USBRESET_MASK; + while (KHCI->USBTRC0 & USB_USBTRC0_USBRESET_MASK); +#endif + tu_memclr(&_dcd, sizeof(_dcd)); KHCI->USBTRC0 |= TU_BIT(6); /* software must set this bit to 1 */ KHCI->BDTPAGE1 = (uint8_t)((uintptr_t)_dcd.bdt >> 8); diff --git a/src/tusb_option.h b/src/tusb_option.h index c792efe6a..bbaa2a53a 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -121,6 +121,7 @@ #define OPT_MCU_KINETIS_KL 1200 ///< NXP KL series #define OPT_MCU_KINETIS_K32L 1201 ///< NXP K32L series #define OPT_MCU_KINETIS_K32 1201 ///< Alias to K32L +#define OPT_MCU_KINETIS_K64 1202 ///< NXP K64 series #define OPT_MCU_MKL25ZXX 1200 ///< Alias to KL (obsolete) #define OPT_MCU_K32L2BXX 1201 ///< Alias to K32 (obsolete) From d0bff6fd3ec9fc133032dea84732451d93d202b4 Mon Sep 17 00:00:00 2001 From: Xelus22 Date: Tue, 25 Jul 2023 23:53:55 +1000 Subject: [PATCH 017/454] 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); From 0161955c22eccea62a783368073042154b3e5976 Mon Sep 17 00:00:00 2001 From: Rocky04 Date: Tue, 8 Aug 2023 17:48:45 +0000 Subject: [PATCH 018/454] 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); From a98b21992263584ebced348b49f082c69171f0ff Mon Sep 17 00:00:00 2001 From: Rocky04 Date: Tue, 8 Aug 2023 18:14:00 +0000 Subject: [PATCH 019/454] 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); From 427ecbbc53f033586c898e130c07d8116258a73d Mon Sep 17 00:00:00 2001 From: Rocky04 Date: Tue, 8 Aug 2023 23:33:47 +0200 Subject: [PATCH 020/454] 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) * From 798ff807b3361a5859945cb23c3d0fd7d1a5679f Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Fri, 11 Aug 2023 18:04:34 +0200 Subject: [PATCH 021/454] 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 From fca08c939c0d04b9485413166b69f8abac6fb083 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Sun, 20 Aug 2023 18:22:07 +0200 Subject: [PATCH 022/454] files taken from yapicoprobe --- src/class/net/ncm.h | 106 ++- src/class/net/ncm_device.c | 1381 ++++++++++++++++++++++++------------ src/class/net/net_device.h | 24 +- 3 files changed, 1047 insertions(+), 464 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,9 +30,46 @@ #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" -// 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 +#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 -#define TU_LOG_DRV(...) TU_LOG(CFG_TUD_NCM_LOG_LEVEL, __VA_ARGS__) +#if 0 + #define DEBUG_OUT(...) printf(__VA_ARGS__) + #define DEBUG_OUT_ENABLED +#else + #define DEBUG_OUT(...) +#endif -//--------------------------------------------------------------------+ -// MACRO CONSTANT TYPEDEF -//--------------------------------------------------------------------+ +#if 0 + #define INFO_OUT(...) printf(__VA_ARGS__) +#else + #define INFO_OUT(...) +#endif -#define NTH16_SIGNATURE 0x484D434E -#define NDP16_SIGNATURE_NCM0 0x304D434E -#define NDP16_SIGNATURE_NCM1 0x314D434E +#if 1 + #define ERROR_OUT(...) printf(__VA_ARGS__) +#else + #define ERROR_OUT(...) +#endif -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; +// 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)) -typedef struct TU_ATTR_PACKED -{ - uint32_t dwSignature; - uint16_t wHeaderLength; - uint16_t wSequence; - uint16_t wBlockLength; - uint16_t wNdpIndex; -} nth16_t; +//----------------------------------------------------------------------------- +// +// 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 TU_ATTR_PACKED -{ - uint16_t wDatagramIndex; - uint16_t wDatagramLength; -} ndp16_datagram_t; +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 -typedef struct TU_ATTR_PACKED -{ - uint32_t dwSignature; - uint16_t wLength; - uint16_t wNextNdpIndex; - ndp16_datagram_t datagram[]; -} ndp16_t; + // 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 -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 -{ - tusb_control_request_t header; - uint32_t downlink, uplink; -}; - -typedef struct -{ - 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 - - uint8_t ep_notif; - uint8_t ep_in; - uint8_t ep_out; - - const ndp16_t *ndp; - uint8_t num_datagrams, current_datagram_index; - - enum { - REPORT_SPEED, - REPORT_CONNECTED, - REPORT_DONE - } report_state; - bool report_pending; - - 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 - - uint16_t nth_sequence; // Sequence number counter for transmitted NTBs - - bool transferring; + // 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; -//--------------------------------------------------------------------+ -// 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 -}; +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static ncm_interface_t ncm_interface; -CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static transmit_ntb_t transmit_ntb[2]; -CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static uint8_t receive_ntb[CFG_TUD_NCM_OUT_NTB_MAX_SIZE]; - -tu_static ncm_interface_t ncm_interface; - -/* - * Set up the NTB state in ncm_interface to be ready to add datagrams. +/** + * This is the NTB parameter structure + * + * \attention + * We are lucky, that byte order is correct */ -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)); -} +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 +}; -/* - * If not already transmitting, start sending the current NTB to the host and swap buffers - * to start filling the other one with datagrams. +// 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. */ -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("notification_xmit(%d, %d) - %d %d\n", force_next, rhport, ncm_interface.notification_xmit_state, ncm_interface.notification_xmit_is_running); -tu_static struct ecm_notify_struct ncm_notify_speed_change = + 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. + */ { - .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("xmit_put_ntb_into_free_list() - %p\n", ncm_interface.xmit_tinyusb_ntb); -void tud_network_recv_renew(void) -{ - if (!ncm_interface.num_datagrams) - { - usbd_edpt_xfer(0, ncm_interface.ep_out, receive_ntb, sizeof(receive_ntb)); - return; - } + if (free_ntb == NULL) { + // can happen due to ZLPs + return; + } - const ndp16_t *ndp = ncm_interface.ndp; - const int i = ncm_interface.current_datagram_index; - ncm_interface.current_datagram_index++; - ncm_interface.num_datagrams--; - - tud_network_recv_cb(receive_ntb + ndp->datagram[i].wDatagramIndex, ndp->datagram[i].wDatagramLength); -} - -//--------------------------------------------------------------------+ -// USBD Driver API -//--------------------------------------------------------------------+ - -void netd_init(void) -{ - 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(); -} - -void netd_reset(uint8_t rhport) -{ - (void) rhport; - - netd_init(); -} - -uint16_t netd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) -{ - // confirm interface hasn't already been allocated - TU_ASSERT(0 == ncm_interface.ep_notif, 0); - - //------------- Management Interface -------------// - ncm_interface.itf_num = itf_desc->bInterfaceNumber; - - uint16_t drv_len = sizeof(tusb_desc_interface_t); - 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 ) - { - drv_len += tu_desc_len(p_desc); - p_desc = tu_desc_next(p_desc); - } - - // 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); - } - - //------------- 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); - - 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); - - 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)); - - // Pair of endpoints - TU_ASSERT(TUSB_DESC_ENDPOINT == tu_desc_type(p_desc), 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; -} - -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) -{ - 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); + 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; } - break; + } + ERROR_OUT("xmit_put_ntb_into_free_list - no entry in free list\n"); // this should not happen +} // xmit_put_ntb_into_free_list - 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; +static xmit_ntb_t *xmit_get_free_ntb(void) +/** + * Get an NTB from the free list + */ +{ + DEBUG_OUT("xmit_get_free_ntb()\n"); - 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(); - } + 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 + */ +{ + 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. + */ +{ + 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])); + + 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 + */ +{ + DEBUG_OUT("xmit_insert_required_zlp(%d,%d)\n", rhport, xferred_bytes); + + if (xferred_bytes == 0 || xferred_bytes % CFG_TUD_NET_ENDPOINT_SIZE != 0) { + return false; + } + + 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); + + // 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. + */ +{ + DEBUG_OUT("xmit_start_if_possible()\n"); + + 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; + } + + 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); + } + + // 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 + */ +{ + 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 (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 + */ +{ + 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 + + +//----------------------------------------------------------------------------- +// +// 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. + */ +{ + DEBUG_OUT("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; + + 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])); + + DEBUG_OUT("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) +/** + * + */ +{ + DEBUG_OUT("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; + } + } + 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. + */ +{ + 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 + + + +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. + */ +{ + DEBUG_OUT("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(ncm_interface.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 + 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 + + + +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); + + DEBUG_OUT("recv_validate_datagram(%p)\n", ntb); + + // + // 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; + } + + // + // check (first) NDP(16) + // + 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); + 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; + } + + 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); + + 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 + + + +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"); + + 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"); + } + 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; + } } - - tud_network_link_state_cb(ncm_interface.itf_data_alt); - } - - 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); - - if (NCM_GET_NTB_PARAMETERS == request->bRequest) - { - tud_control_xfer(rhport, request, (void*)(uintptr_t) &ntb_parameters, sizeof(ntb_parameters)); - } - - break; - - // unsupported request - default: return false; - } - - return true; -} - -static void handle_incoming_datagram(uint32_t len) -{ - uint32_t size = len; - - if (len == 0) { - return; - } - - 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, ); - - 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++; - } - - tud_network_recv_renew(); -} - -bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) -{ - (void) rhport; - (void) result; - - /* new datagram receive_ntb */ - if (ep_addr == ncm_interface.ep_out ) - { - handle_incoming_datagram(xferred_bytes); - } - - /* data transmission finished */ - if (ep_addr == ncm_interface.ep_in ) - { - if (ncm_interface.transferring) { - ncm_interface.transferring = false; } +} // recv_transfer_datagram_to_glue_logic - // 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(); - } - } - if (ep_addr == ncm_interface.ep_notif ) - { - ncm_interface.report_pending = false; - ncm_report(); - } +//----------------------------------------------------------------------------- +// +// all the tud_network_*() stuff (glue logic -> driver) +// - return true; -} -// poll network driver for its ability to accept another packet to transmit 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_VERIFY(ncm_interface.itf_data_alt == 1); + DEBUG_OUT("tud_network_can_xmit(%d)\n", size); - if (ncm_interface.datagram_count >= ncm_interface.max_datagrams_per_ntb) { - TU_LOG_DRV("NTB full [by count]\r\n"); + 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 - 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) +/** + * Put a datagram into a waiting NTB. + * If currently no transmission is started, then initiate transmission. + */ { - transmit_ntb_t *ntb = &transmit_ntb[ncm_interface.current_ntb]; - size_t next_datagram_offset = ncm_interface.next_datagram_offset; + DEBUG_OUT("tud_network_xmit(%p, %d)\n", ref, arg); - uint16_t size = tud_network_xmit_cb(ntb->data + next_datagram_offset, ref, arg); + if (ncm_interface.xmit_glue_ntb == NULL) { + ERROR_OUT("tud_network_xmit: no buffer\n"); // must not happen (really) + return; + } - ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramIndex = ncm_interface.next_datagram_offset; - ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramLength = size; + xmit_ntb_t *ntb = ncm_interface.xmit_glue_ntb; - ncm_interface.datagram_count++; - next_datagram_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); - // 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); + // 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; - ncm_interface.next_datagram_offset = next_datagram_offset; + ntb->nth.wBlockLength += size + XMIT_ALIGN_OFFSET(size); - ncm_start_tx(); -} + if (ntb->nth.wBlockLength > CFG_TUD_NCM_OUT_NTB_MAX_SIZE) { + ERROR_OUT("tud_network_xmit: buffer overflow\n"); // must not happen (really) + return; + } -#endif + 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. + */ +{ + DEBUG_OUT("tud_network_recv_renew()\n"); + + 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 + */ +{ + DEBUG_OUT("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. + */ +{ + DEBUG_OUT("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 + + + +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); + } + + // + // 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); + + // + // 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); + + 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. + */ +{ + 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); + } + + 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. + */ +{ + DEBUG_OUT("netd_control_xfer_cb(%d, %d, %p)\n", rhport, stage, request); + + 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: { + 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; + + case TUSB_REQ_TYPE_CLASS: + TU_VERIFY(ncm_interface.itf_num == request->wIndex, false); + + DEBUG_OUT(" 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"); + tud_control_xfer(rhport, request, (void*) (uintptr_t) &ntb_parameters, sizeof(ntb_parameters)); + } + break; + + // unsupported request + default: + return false ; + } + + 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); From d5da303f450ce0e1004121af4a40a512371e9353 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Sun, 20 Aug 2023 18:22:07 +0200 Subject: [PATCH 023/454] 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); From e4c18c101cf5dc78f6bd1034aae7f0f7e22b7e47 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Sun, 20 Aug 2023 18:22:07 +0200 Subject: [PATCH 024/454] 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 From 28107326da6cbc462bf6644f1f6edd5d0bcb43b8 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Sun, 20 Aug 2023 18:22:07 +0200 Subject: [PATCH 025/454] 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 From 2c1addff4f853586c8d9590e3f93d79fc7c6e250 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Sun, 20 Aug 2023 18:27:06 +0200 Subject: [PATCH 026/454] 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 From 588b758717f3c22aa8046d61247b9967de8840b7 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 28 Aug 2023 17:34:22 +0700 Subject: [PATCH 027/454] rename OPT_MCU_KINETIS_K64 to OPT_MCU_KINETIS_K --- hw/bsp/board_mcu.h | 2 +- src/common/tusb_mcu.h | 2 +- src/portable/nxp/khci/dcd_khci.c | 6 +++--- src/tusb_option.h | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/hw/bsp/board_mcu.h b/hw/bsp/board_mcu.h index 3928435f0..b0f7891b4 100644 --- a/hw/bsp/board_mcu.h +++ b/hw/bsp/board_mcu.h @@ -47,7 +47,7 @@ #elif TU_CHECK_MCU(OPT_MCU_LPC51UXX, OPT_MCU_LPC54XXX, OPT_MCU_LPC55XX, OPT_MCU_MCXN9) #include "fsl_device_registers.h" -#elif TU_CHECK_MCU(OPT_MCU_KINETIS_KL, OPT_MCU_KINETIS_K32L, OPT_MCU_KINETIS_K64) +#elif TU_CHECK_MCU(OPT_MCU_KINETIS_KL, OPT_MCU_KINETIS_K32L, OPT_MCU_KINETIS_K) #include "fsl_device_registers.h" #elif CFG_TUSB_MCU == OPT_MCU_NRF5X diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 4a0c5acef..d983f8677 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -97,7 +97,7 @@ #define TUP_DCD_ENDPOINT_MAX 8 #define TUP_RHPORT_HIGHSPEED 1 -#elif TU_CHECK_MCU(OPT_MCU_KINETIS_KL, OPT_MCU_KINETIS_K32L, OPT_MCU_KINETIS_K64) +#elif TU_CHECK_MCU(OPT_MCU_KINETIS_KL, OPT_MCU_KINETIS_K32L, OPT_MCU_KINETIS_K) #define TUP_USBIP_CHIPIDEA_FS #define TUP_USBIP_CHIPIDEA_FS_KINETIS #define TUP_DCD_ENDPOINT_MAX 16 diff --git a/src/portable/nxp/khci/dcd_khci.c b/src/portable/nxp/khci/dcd_khci.c index d957338ad..2293d1b59 100644 --- a/src/portable/nxp/khci/dcd_khci.c +++ b/src/portable/nxp/khci/dcd_khci.c @@ -269,10 +269,10 @@ void dcd_init(uint8_t rhport) { (void) rhport; -#if (CFG_TUSB_MCU == OPT_MCU_KINETIS_K64) +#if (CFG_TUSB_MCU == OPT_MCU_KINETIS_K) uint32_t clk_recover_irc_en; uint32_t clk_recover_ctrl; - + clk_recover_irc_en = KHCI->CLK_RECOVER_IRC_EN; clk_recover_ctrl = KHCI->CLK_RECOVER_CTRL; @@ -284,7 +284,7 @@ void dcd_init(uint8_t rhport) #else KHCI->USBTRC0 |= USB_USBTRC0_USBRESET_MASK; while (KHCI->USBTRC0 & USB_USBTRC0_USBRESET_MASK); -#endif +#endif tu_memclr(&_dcd, sizeof(_dcd)); KHCI->USBTRC0 |= TU_BIT(6); /* software must set this bit to 1 */ diff --git a/src/tusb_option.h b/src/tusb_option.h index bbaa2a53a..bf2667c4c 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -121,7 +121,7 @@ #define OPT_MCU_KINETIS_KL 1200 ///< NXP KL series #define OPT_MCU_KINETIS_K32L 1201 ///< NXP K32L series #define OPT_MCU_KINETIS_K32 1201 ///< Alias to K32L -#define OPT_MCU_KINETIS_K64 1202 ///< NXP K64 series +#define OPT_MCU_KINETIS_K 1202 ///< NXP K series #define OPT_MCU_MKL25ZXX 1200 ///< Alias to KL (obsolete) #define OPT_MCU_K32L2BXX 1201 ///< Alias to K32 (obsolete) From aa0fabd51d3ed855ccb337602c6a0083bb50f648 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 28 Aug 2023 17:44:29 +0700 Subject: [PATCH 028/454] add kinetis_k family and teensy_35 - teensy_35 is not able to blink led with board_test though, probably due to clock config. --- .idea/cmake.xml | 1 + hw/bsp/family_support.cmake | 12 ++ .../kinetis_k/FreeRTOSConfig/FreeRTOSConfig.h | 165 ++++++++++++++++ hw/bsp/kinetis_k/boards/teensy_35/board.cmake | 17 ++ hw/bsp/kinetis_k/boards/teensy_35/board.h | 48 +++++ hw/bsp/kinetis_k/boards/teensy_35/board.mk | 23 +++ .../boards/teensy_35/board/clock_config.c | 186 ++++++++++++++++++ .../boards/teensy_35/board/clock_config.h | 69 +++++++ .../boards/teensy_35/board/pin_mux.c | 61 ++++++ .../boards/teensy_35/board/pin_mux.h | 45 +++++ .../kinetis_k/boards/teensy_35/teensy_35.mex | 184 +++++++++++++++++ hw/bsp/kinetis_k/family.c | 142 +++++++++++++ hw/bsp/kinetis_k/family.cmake | 112 +++++++++++ hw/bsp/kinetis_k/family.mk | 34 ++++ tools/get_deps.py | 2 +- 15 files changed, 1100 insertions(+), 1 deletion(-) create mode 100644 hw/bsp/kinetis_k/FreeRTOSConfig/FreeRTOSConfig.h create mode 100644 hw/bsp/kinetis_k/boards/teensy_35/board.cmake create mode 100644 hw/bsp/kinetis_k/boards/teensy_35/board.h create mode 100644 hw/bsp/kinetis_k/boards/teensy_35/board.mk create mode 100644 hw/bsp/kinetis_k/boards/teensy_35/board/clock_config.c create mode 100644 hw/bsp/kinetis_k/boards/teensy_35/board/clock_config.h create mode 100644 hw/bsp/kinetis_k/boards/teensy_35/board/pin_mux.c create mode 100644 hw/bsp/kinetis_k/boards/teensy_35/board/pin_mux.h create mode 100644 hw/bsp/kinetis_k/boards/teensy_35/teensy_35.mex create mode 100644 hw/bsp/kinetis_k/family.c create mode 100644 hw/bsp/kinetis_k/family.cmake create mode 100644 hw/bsp/kinetis_k/family.mk diff --git a/.idea/cmake.xml b/.idea/cmake.xml index 788f70433..e8f65dcce 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -39,6 +39,7 @@ + diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index b2e61a824..b8cbbee38 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -379,6 +379,18 @@ function(family_flash_pyocd TARGET) endfunction() +# Add flash teensy_cli target +function(family_flash_teensy TARGET) + if (NOT DEFINED TEENSY_CLI) + set(TEENSY_CLI teensy_loader_cli) + endif () + + add_custom_target(${TARGET}-teensy + DEPENDS ${TARGET} + COMMAND ${TEENSY_CLI} --mcu=${TEENSY_MCU} -w -s $/${TARGET}.hex + ) +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/kinetis_k/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/kinetis_k/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..a46af1759 --- /dev/null +++ b/hw/bsp/kinetis_k/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,165 @@ +/* + * 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 +#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 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 0 +#define configSUPPORT_DYNAMIC_ALLOCATION 1 + +/* 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<C1 = ((MCG->C1 & ~MCG_C1_FRDIV_MASK) | MCG_C1_FRDIV(frdiv)); +} + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ +void BOARD_InitBootClocks(void) +{ + BOARD_BootClockRUN(); +} + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockRUN +called_from_default_init: true +outputs: +- {id: Bus_clock.outFreq, value: 60 MHz} +- {id: Core_clock.outFreq, value: 120 MHz} +- {id: Flash_clock.outFreq, value: 24 MHz} +- {id: FlexBus_clock.outFreq, value: 40 MHz} +- {id: LPO_clock.outFreq, value: 1 kHz} +- {id: MCGFFCLK.outFreq, value: 500 kHz} +- {id: PLLFLLCLK.outFreq, value: 120 MHz} +- {id: System_clock.outFreq, value: 120 MHz} +- {id: USB48MCLK.outFreq, value: 48 MHz} +settings: +- {id: MCGMode, value: PEE} +- {id: MCG.FRDIV.scale, value: '32'} +- {id: MCG.IREFS.sel, value: MCG.FRDIV} +- {id: MCG.PLLS.sel, value: MCG.PLL} +- {id: MCG.PRDIV.scale, value: '4'} +- {id: MCG.VDIV.scale, value: '30'} +- {id: MCG_C2_RANGE0_CFG, value: Very_high} +- {id: MCG_C2_RANGE0_FRDIV_CFG, value: Very_high} +- {id: MCG_C5_PLLCLKEN0_CFG, value: Enabled} +- {id: RTC_CR_CLKO_CFG, value: Disabled} +- {id: RTC_CR_OSC_CAP_LOAD_CFG, value: SC10PF} +- {id: SIM.OUTDIV2.scale, value: '2'} +- {id: SIM.OUTDIV3.scale, value: '3'} +- {id: SIM.OUTDIV4.scale, value: '5'} +- {id: SIM.PLLFLLSEL.sel, value: MCG.MCGPLLCLK} +- {id: SIM.USBDIV.scale, value: '5'} +- {id: SIM.USBFRAC.scale, value: '2'} +- {id: SIM.USBSRCSEL.sel, value: SIM.USBDIV} +- {id: USBClkConfig, value: 'yes'} +sources: +- {id: OSC.OSC.outFreq, value: 16 MHz, enabled: true} +- {id: RTC.RTC32kHz.outFreq, value: 32.768 kHz, enabled: true} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockRUN configuration + ******************************************************************************/ +const mcg_config_t mcgConfig_BOARD_BootClockRUN = + { + .mcgMode = kMCG_ModePEE, /* PEE - PLL Engaged External */ + .irclkEnableMode = MCG_IRCLK_DISABLE, /* MCGIRCLK disabled */ + .ircs = kMCG_IrcSlow, /* Slow internal reference clock selected */ + .fcrdiv = 0x1U, /* Fast IRC divider: divided by 2 */ + .frdiv = 0x0U, /* FLL reference clock divider: divided by 32 */ + .drs = kMCG_DrsLow, /* Low frequency range */ + .dmx32 = kMCG_Dmx32Default, /* DCO has a default range of 25% */ + .oscsel = kMCG_OscselOsc, /* Selects System Oscillator (OSCCLK) */ + .pll0Config = + { + .enableMode = kMCG_PllEnableIndependent,/* MCGPLLCLK enabled independent of MCG clock mode, MCGPLLCLK disabled in STOP mode */ + .prdiv = 0x3U, /* PLL Reference divider: divided by 4 */ + .vdiv = 0x6U, /* VCO divider: multiplied by 30 */ + }, + }; +const sim_clock_config_t simConfig_BOARD_BootClockRUN = + { + .pllFllSel = SIM_PLLFLLSEL_MCGPLLCLK_CLK, /* PLLFLL select: MCGPLLCLK clock */ + .er32kSrc = SIM_OSC32KSEL_OSC32KCLK_CLK, /* OSC32KSEL select: OSC32KCLK clock */ + .clkdiv1 = 0x1240000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV2: /2, OUTDIV3: /3, OUTDIV4: /5 */ + }; +const osc_config_t oscConfig_BOARD_BootClockRUN = + { + .freq = 16000000U, /* Oscillator frequency: 16000000Hz */ + .capLoad = (OSC_CAP0P), /* Oscillator capacity load: 0pF */ + .workMode = kOSC_ModeExt, /* Use external clock */ + .oscerConfig = + { + .enableMode = OSC_ER_CLK_DISABLE, /* Disable external reference clock */ + } + }; + +/******************************************************************************* + * Code for BOARD_BootClockRUN configuration + ******************************************************************************/ +void BOARD_BootClockRUN(void) +{ + /* Set the system clock dividers in SIM to safe value. */ + CLOCK_SetSimSafeDivs(); + /* Initializes OSC0 according to board configuration. */ + CLOCK_InitOsc0(&oscConfig_BOARD_BootClockRUN); + CLOCK_SetXtal0Freq(oscConfig_BOARD_BootClockRUN.freq); + /* Configure FLL external reference divider (FRDIV). */ + CLOCK_CONFIG_SetFllExtRefDiv(mcgConfig_BOARD_BootClockRUN.frdiv); + /* Set MCG to PEE mode. */ + CLOCK_BootToPeeMode(mcgConfig_BOARD_BootClockRUN.oscsel, + kMCG_PllClkSelPll0, + &mcgConfig_BOARD_BootClockRUN.pll0Config); + /* Set the clock configuration in SIM module. */ + CLOCK_SetSimConfig(&simConfig_BOARD_BootClockRUN); + /* Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; + /* Enable USB FS clock. */ + CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcPll0, SIM_USB_CLK_120000000HZ); +} diff --git a/hw/bsp/kinetis_k/boards/teensy_35/board/clock_config.h b/hw/bsp/kinetis_k/boards/teensy_35/board/clock_config.h new file mode 100644 index 000000000..8601da9c2 --- /dev/null +++ b/hw/bsp/kinetis_k/boards/teensy_35/board/clock_config.h @@ -0,0 +1,69 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _CLOCK_CONFIG_H_ +#define _CLOCK_CONFIG_H_ + +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define BOARD_XTAL0_CLK_HZ 16000000U /*!< Board xtal0 frequency in Hz */ + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes default configuration of clocks. + * + */ +void BOARD_InitBootClocks(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockRUN configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 120000000U /*!< Core clock frequency: 120000000Hz */ + +/*! @brief MCG set for BOARD_BootClockRUN configuration. + */ +extern const mcg_config_t mcgConfig_BOARD_BootClockRUN; +/*! @brief SIM module set for BOARD_BootClockRUN configuration. + */ +extern const sim_clock_config_t simConfig_BOARD_BootClockRUN; +/*! @brief OSC set for BOARD_BootClockRUN configuration. + */ +extern const osc_config_t oscConfig_BOARD_BootClockRUN; + +/******************************************************************************* + * API for BOARD_BootClockRUN configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockRUN(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +#endif /* _CLOCK_CONFIG_H_ */ diff --git a/hw/bsp/kinetis_k/boards/teensy_35/board/pin_mux.c b/hw/bsp/kinetis_k/boards/teensy_35/board/pin_mux.c new file mode 100644 index 000000000..d2c51e5c6 --- /dev/null +++ b/hw/bsp/kinetis_k/boards/teensy_35/board/pin_mux.c @@ -0,0 +1,61 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Pins v13.1 +processor: MK64FX512xxx12 +package_id: MK64FX512VLQ12 +mcu_data: ksdk2_0 +processor_version: 13.0.1 + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +#include "fsl_common.h" +#include "fsl_port.h" +#include "pin_mux.h" + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitBootPins + * Description : Calls initialization functions. + * + * END ****************************************************************************************************************/ +void BOARD_InitBootPins(void) +{ + BOARD_InitPins(); +} + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitPins: +- options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: '110', peripheral: GPIOC, signal: 'GPIO, 5', pin_signal: PTC5/LLWU_P9/SPI0_SCK/LPTMR0_ALT2/I2S0_RXD0/FB_AD10/CMP0_OUT/FTM0_CH2} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitPins(void) +{ + /* Port C Clock Gate Control: Clock enabled */ + CLOCK_EnableClock(kCLOCK_PortC); + + /* PORTC5 (pin 110) is configured as PTC5 */ + PORT_SetPinMux(PORTC, 5U, kPORT_MuxAsGpio); +} +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/kinetis_k/boards/teensy_35/board/pin_mux.h b/hw/bsp/kinetis_k/boards/teensy_35/board/pin_mux.h new file mode 100644 index 000000000..598ae8e9f --- /dev/null +++ b/hw/bsp/kinetis_k/boards/teensy_35/board/pin_mux.h @@ -0,0 +1,45 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _PIN_MUX_H_ +#define _PIN_MUX_H_ + +/*! + * @addtogroup pin_mux + * @{ + */ + +/*********************************************************************************************************************** + * API + **********************************************************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Calls initialization functions. + * + */ +void BOARD_InitBootPins(void); + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitPins(void); + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ +#endif /* _PIN_MUX_H_ */ + +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/kinetis_k/boards/teensy_35/teensy_35.mex b/hw/bsp/kinetis_k/boards/teensy_35/teensy_35.mex new file mode 100644 index 000000000..52a087026 --- /dev/null +++ b/hw/bsp/kinetis_k/boards/teensy_35/teensy_35.mex @@ -0,0 +1,184 @@ + + + + MK64FX512xxx12 + MK64FX512VLQ12 + ksdk2_0 + + + + + + + true + false + false + true + false + + + + + + + + + 13.0.1 + + + + Configures pin routing and optionally pin electrical features. + + true + core0 + true + + + + + true + + + + + true + + + + + + + + + + + + + + + + 13.0.1 + + + + + + + + + true + + + + + INPUT + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + N/A + + + + + + + 13.0.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + N/A + + + + diff --git a/hw/bsp/kinetis_k/family.c b/hw/bsp/kinetis_k/family.c new file mode 100644 index 000000000..b6e0e4093 --- /dev/null +++ b/hw/bsp/kinetis_k/family.c @@ -0,0 +1,142 @@ +/* + * 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. + */ + +#include "bsp/board.h" +#include "board.h" +#include "fsl_device_registers.h" +#include "fsl_gpio.h" +#include "fsl_port.h" +#include "fsl_clock.h" +#include "fsl_uart.h" + +#include "board/clock_config.h" +#include "board/pin_mux.h" + +//--------------------------------------------------------------------+ +// Forward USB interrupt events to TinyUSB IRQ Handler +//--------------------------------------------------------------------+ +void USB0_IRQHandler(void) { +#if CFG_TUH_ENABLED + tuh_int_handler(0); +#endif +#if CFG_TUD_ENABLED + tud_int_handler(0); +#endif +} + +void board_init(void) { + BOARD_InitBootPins(); + BOARD_BootClockRUN(); + 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 + + + // LED + gpio_pin_config_t led_config = { kGPIO_DigitalOutput, 0 }; + GPIO_PinInit(LED_PORT, LED_PIN, &led_config); + board_led_write(false); + +#if defined(BUTTON_PORT) && defined(BUTTON_PIN) + // Button + CLOCK_EnableClock(BUTTON_PIN_CLOCK); + port_pin_config_t button_port = { + .pullSelect = kPORT_PullUp, + .mux = BUTTON_PIN_FUNCTION, + }; + PORT_SetPinConfig(BUTTON_PIN_PORT, BUTTON_PIN, &button_port); + gpio_pin_config_t button_config = { kGPIO_DigitalInput, 0 }; + GPIO_PinInit(BUTTON_PORT, BUTTON_PIN, &button_config); +#endif + +#if 0 + // UART + CLOCK_EnableClock(UART_PIN_CLOCK); + PORT_SetPinMux(UART_PIN_PORT, UART_PIN_RX, UART_PIN_FUNCTION); + PORT_SetPinMux(UART_PIN_PORT, UART_PIN_TX, UART_PIN_FUNCTION); + SIM->SOPT5 = ((SIM->SOPT5 & + (~(SIM_SOPT5_UART0TXSRC_MASK | SIM_SOPT5_UART0RXSRC_MASK))) + | SIM_SOPT5_UART0TXSRC(SOPT5_UART0TXSRC_UART_TX) + | SIM_SOPT5_UART0RXSRC(SOPT5_UART0RXSRC_UART_RX) + ); + + 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)); +#endif + + // USB + CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcPll0, CLOCK_GetFreq(kCLOCK_PllFllSelClk)); +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) { + GPIO_PinWrite(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); +} + +uint32_t board_button_read(void) { +#if defined(BUTTON_PORT) && defined(BUTTON_PIN) + return BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_PORT, BUTTON_PIN); +#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) { + (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/kinetis_k/family.cmake b/hw/bsp/kinetis_k/family.cmake new file mode 100644 index 000000000..853316c3a --- /dev/null +++ b/hw/bsp/kinetis_k/family.cmake @@ -0,0 +1,112 @@ +include_guard() + +if (NOT BOARD) + message(FATAL_ERROR "BOARD not specified") +endif () + +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-m4 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/tools/cmake/toolchain/arm_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS KINETIS_K CACHE INTERNAL "") + + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (NOT TARGET ${BOARD_TARGET}) + add_library(${BOARD_TARGET} STATIC + # driver + ${SDK_DIR}/drivers/gpio/fsl_gpio.c + ${SDK_DIR}/drivers/uart/fsl_uart.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 + ) + 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/port + ${SDK_DIR}/drivers/smc + ${SDK_DIR}/drivers/uart + ) + + update_board(${BOARD_TARGET}) + + # LD_FILE and STARTUP_FILE can be defined in board.cmake + set(STARTUP_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_VARIANT}.S) + + target_sources(${BOARD_TARGET} PUBLIC + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + # nanolib + --specs=nosys.specs + --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () + 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_K ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/chipidea/ci_fs/dcd_ci_fs.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_k/family.mk b/hw/bsp/kinetis_k/family.mk new file mode 100644 index 000000000..de352a6a9 --- /dev/null +++ b/hw/bsp/kinetis_k/family.mk @@ -0,0 +1,34 @@ +SDK_DIR = hw/mcu/nxp/mcux-sdk +DEPS_SUBMODULES += $(SDK_DIR) lib/CMSIS_5 + +MCU_DIR = $(SDK_DIR)/devices/${MCU_VARIANT} +include $(TOP)/$(BOARD_PATH)/board.mk +CPU_CORE ?= cortex-m4 + +CFLAGS += \ + -DCFG_TUSB_MCU=OPT_MCU_KINETIS_K \ + +LDFLAGS += \ + -Wl,--defsym,__stack_size__=0x400 \ + -Wl,--defsym,__heap_size__=0 + +SRC_C += \ + src/portable/nxp/khci/dcd_khci.c \ + src/portable/nxp/khci/hcd_khci.c \ + $(MCU_DIR)/system_${MCU_VARIANT}.c \ + $(MCU_DIR)/drivers/fsl_clock.c \ + $(SDK_DIR)/drivers/gpio/fsl_gpio.c \ + $(SDK_DIR)/drivers/uart/fsl_uart.c \ + +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ + $(TOP)/$(MCU_DIR) \ + $(TOP)/$(MCU_DIR)/drivers \ + $(TOP)/$(SDK_DIR)/drivers/common \ + $(TOP)/$(SDK_DIR)/drivers/gpio \ + $(TOP)/$(SDK_DIR)/drivers/port \ + $(TOP)/$(SDK_DIR)/drivers/smc \ + $(TOP)/$(SDK_DIR)/drivers/uart \ + +SRC_S += ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_VARIANT}.S diff --git a/tools/get_deps.py b/tools/get_deps.py index 9b89c5e4c..388a68c83 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -52,7 +52,7 @@ deps_optional = { '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'], + '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', '58879cfa0eca5725d8db6443ec17f8896a321042', 'rp2040'], From 1dd9fa3f307e6f3a847619d587529ea17608c1a3 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 31 Aug 2023 20:24:56 +0200 Subject: [PATCH 029/454] 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; From 92025b00f0a7d7d0b45d8a2bcc3f3704dbe77733 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 31 Aug 2023 20:32:42 +0200 Subject: [PATCH 030/454] code review: add NCM options in example config --- .../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 } From 51ea467350f84b92439d0890a4b12bd55e2eff91 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Thu, 31 Aug 2023 20:34:12 +0200 Subject: [PATCH 031/454] 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 From 745c154dbc33bff9a45bc8bee636e7e90152a9c7 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Fri, 8 Sep 2023 07:00:08 +0200 Subject: [PATCH 032/454] 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 From f1d3663d24f04dbb68732f8287c516abd0b7ecfb Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Fri, 8 Sep 2023 07:01:13 +0200 Subject: [PATCH 033/454] 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; } From 3e8cf3ec8c861233c2a15750a38c38deb2302094 Mon Sep 17 00:00:00 2001 From: Ryan Solorzano Date: Tue, 12 Sep 2023 11:32:23 -0700 Subject: [PATCH 034/454] 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 //--------------------------------------------------------------------+ From a3d9eb43f1f0bd1632e4d8fe4fb3f3fc57778f16 Mon Sep 17 00:00:00 2001 From: Ryan Solorzano Date: Tue, 12 Sep 2023 12:09:39 -0700 Subject: [PATCH 035/454] 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 ),\ From 11fba8433474a0653047823a25a749183a7d1ac2 Mon Sep 17 00:00:00 2001 From: Rocky04 Date: Wed, 13 Sep 2023 21:29:04 +0000 Subject: [PATCH 036/454] 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 From 81e63ed6d865d43b634ed6bf2d3df3ae29135913 Mon Sep 17 00:00:00 2001 From: Rocky04 Date: Wed, 13 Sep 2023 22:03:44 +0000 Subject: [PATCH 037/454] 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 From 997c29ba0517604859a13aa73a8a80341d549898 Mon Sep 17 00:00:00 2001 From: Rocky04 Date: Thu, 14 Sep 2023 18:46:56 +0000 Subject: [PATCH 038/454] 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 From 288f24b294a96f8edc12943d21278020e3e398e3 Mon Sep 17 00:00:00 2001 From: Rocky04 Date: Thu, 14 Sep 2023 18:50:13 +0000 Subject: [PATCH 039/454] 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 }; From 46977a011d88b8954083de0fc8201350bcda5884 Mon Sep 17 00:00:00 2001 From: Rocky04 Date: Thu, 14 Sep 2023 18:53:55 +0000 Subject: [PATCH 040/454] 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; From c87fba1dc3b8cc8a1f72aca312bb5c0d1312464b Mon Sep 17 00:00:00 2001 From: Rocky04 Date: Thu, 14 Sep 2023 19:03:16 +0000 Subject: [PATCH 041/454] 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; From 337d03d36883c5067d102900e6ce14e98ce3f8f0 Mon Sep 17 00:00:00 2001 From: Rocky04 Date: Thu, 14 Sep 2023 19:16:45 +0000 Subject: [PATCH 042/454] 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 From f88a5bb03b2504df272d2cd285b17e66f11dfc64 Mon Sep 17 00:00:00 2001 From: Shawn Hoffman Date: Tue, 17 Oct 2023 19:26:11 -0700 Subject: [PATCH 043/454] 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 From a39be99a58847318e67d06db17c24e481d318f08 Mon Sep 17 00:00:00 2001 From: IngHK Date: Tue, 26 Dec 2023 12:24:54 +0100 Subject: [PATCH 044/454] improved hex debug print, improved USBH debug prints, added pid/vid debug print --- src/common/tusb_debug.h | 2 +- src/host/usbh.c | 29 ++++++++++++++++------------- src/host/usbh_pvt.h | 6 +++++- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/common/tusb_debug.h b/src/common/tusb_debug.h index 0f4dc93f3..8db1606ae 100644 --- a/src/common/tusb_debug.h +++ b/src/common/tusb_debug.h @@ -76,7 +76,7 @@ static inline void tu_print_buf(uint8_t const* buf, uint32_t bufsize) { #define TU_LOG1_MEM tu_print_mem #define TU_LOG1_BUF(_x, _n) tu_print_buf((uint8_t const*)(_x), _n) #define TU_LOG1_INT(_x) tu_printf(#_x " = %ld\r\n", (unsigned long) (_x) ) -#define TU_LOG1_HEX(_x) tu_printf(#_x " = %lX\r\n", (unsigned long) (_x) ) +#define TU_LOG1_HEX(_x) tu_printf(#_x " = 0x%lX\r\n", (unsigned long) (_x) ) // Log Level 2: Warn #if CFG_TUSB_DEBUG >= 2 diff --git a/src/host/usbh.c b/src/host/usbh.c index 4d30d9f81..ee7424ed9 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -291,6 +291,9 @@ bool tuh_vid_pid_get(uint8_t dev_addr, uint16_t *vid, uint16_t *pid) { *vid = dev->vid; *pid = dev->pid; + TU_LOG_HEX_USBH(*vid); + TU_LOG_HEX_USBH(*pid); + return true; } @@ -340,12 +343,12 @@ bool tuh_init(uint8_t controller_id) { if ( tuh_inited() ) return true; TU_LOG_USBH("USBH init on controller %u\r\n", controller_id); - TU_LOG_INT(CFG_TUH_LOG_LEVEL, sizeof(usbh_device_t)); - TU_LOG_INT(CFG_TUH_LOG_LEVEL, sizeof(hcd_event_t)); - TU_LOG_INT(CFG_TUH_LOG_LEVEL, sizeof(_ctrl_xfer)); - TU_LOG_INT(CFG_TUH_LOG_LEVEL, sizeof(tuh_xfer_t)); - TU_LOG_INT(CFG_TUH_LOG_LEVEL, sizeof(tu_fifo_t)); - TU_LOG_INT(CFG_TUH_LOG_LEVEL, sizeof(tu_edpt_stream_t)); + TU_LOG_INT_USBH(sizeof(usbh_device_t)); + TU_LOG_INT_USBH(sizeof(hcd_event_t)); + TU_LOG_INT_USBH(sizeof(_ctrl_xfer)); + TU_LOG_INT_USBH(sizeof(tuh_xfer_t)); + TU_LOG_INT_USBH(sizeof(tu_fifo_t)); + TU_LOG_INT_USBH(sizeof(tu_edpt_stream_t)); // Event queue _usbh_q = osal_queue_create( &_usbh_qdef ); @@ -589,7 +592,7 @@ bool tuh_control_xfer (tuh_xfer_t* xfer) { TU_LOG_USBH("[%u:%u] %s: ", rhport, daddr, (xfer->setup->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && xfer->setup->bRequest <= TUSB_REQ_SYNCH_FRAME) ? tu_str_std_request[xfer->setup->bRequest] : "Class Request"); - TU_LOG_BUF(CFG_TUH_LOG_LEVEL, xfer->setup, 8); + TU_LOG_BUF_USBH(xfer->setup, 8); TU_LOG_USBH("\r\n"); if (xfer->complete_cb) { @@ -665,9 +668,9 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result tusb_control_request_t const * request = &_ctrl_xfer.request; if (XFER_RESULT_SUCCESS != result) { - TU_LOG1("[%u:%u] Control %s, xferred_bytes = %lu\r\n", rhport, dev_addr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED", xferred_bytes); - TU_LOG1_BUF(request, 8); - TU_LOG1("\r\n"); + TU_LOG_USBH("[%u:%u] Control %s, xferred_bytes = %lu\r\n", rhport, dev_addr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED", xferred_bytes); + TU_LOG_BUF_USBH(request, 8); + TU_LOG_USBH("\r\n"); // terminate transfer if any stage failed _xfer_complete(dev_addr, result); @@ -685,7 +688,7 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result case CONTROL_STAGE_DATA: if (request->wLength) { TU_LOG_USBH("[%u:%u] Control data:\r\n", rhport, dev_addr); - TU_LOG_MEM(CFG_TUH_LOG_LEVEL, _ctrl_xfer.buffer, xferred_bytes, 2); + TU_LOG_MEM_USBH(_ctrl_xfer.buffer, xferred_bytes, 2); } _ctrl_xfer.actual_len = (uint16_t) xferred_bytes; @@ -860,7 +863,7 @@ bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * b // HCD error, mark endpoint as ready to allow next transfer ep_state->busy = 0; ep_state->claimed = 0; - TU_LOG1("Failed\r\n"); + TU_LOG_USBH("Failed\r\n"); // TU_BREAKPOINT(); return false; } @@ -1318,7 +1321,7 @@ static void process_enumeration(tuh_xfer_t* xfer) { if ( retry ) { failed_count++; osal_task_delay(ATTEMPT_DELAY_MS); // delay a bit - TU_LOG1("Enumeration attempt %u\r\n", failed_count); + TU_LOG_USBH("Enumeration attempt %u\r\n", failed_count); retry = tuh_control_xfer(xfer); } diff --git a/src/host/usbh_pvt.h b/src/host/usbh_pvt.h index 4a97a1c18..4ed2a72b5 100644 --- a/src/host/usbh_pvt.h +++ b/src/host/usbh_pvt.h @@ -35,7 +35,11 @@ extern "C" { #endif -#define TU_LOG_USBH(...) TU_LOG(CFG_TUH_LOG_LEVEL, __VA_ARGS__) +#define TU_LOG_USBH(...) TU_LOG(CFG_TUH_LOG_LEVEL, __VA_ARGS__) +#define TU_LOG_MEM_USBH(...) TU_LOG_MEM(CFG_TUH_LOG_LEVEL, __VA_ARGS__) +#define TU_LOG_BUF_USBH(...) TU_LOG_BUF(CFG_TUH_LOG_LEVEL, __VA_ARGS__) +#define TU_LOG_INT_USBH(...) TU_LOG_INT(CFG_TUH_LOG_LEVEL, __VA_ARGS__) +#define TU_LOG_HEX_USBH(...) TU_LOG_HEX(CFG_TUH_LOG_LEVEL, __VA_ARGS__) enum { USBH_EPSIZE_BULK_MAX = (TUH_OPT_HIGH_SPEED ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS) From c2bbcc9f60a2b7293fad4e24468d3f045fde28ee Mon Sep 17 00:00:00 2001 From: IngHK Date: Tue, 26 Dec 2023 20:14:03 +0100 Subject: [PATCH 045/454] initial support of CH34x CDC device --- examples/host/cdc_msc_hid/src/tusb_config.h | 1 + .../cdc_msc_hid_freertos/src/tusb_config.h | 1 + src/class/cdc/cdc_host.c | 466 +++++++++++++++++- src/class/cdc/serial/ch34x.h | 113 +++++ src/tusb_option.h | 17 + 5 files changed, 595 insertions(+), 3 deletions(-) create mode 100644 src/class/cdc/serial/ch34x.h diff --git a/examples/host/cdc_msc_hid/src/tusb_config.h b/examples/host/cdc_msc_hid/src/tusb_config.h index 61abb85eb..76d59c316 100644 --- a/examples/host/cdc_msc_hid/src/tusb_config.h +++ b/examples/host/cdc_msc_hid/src/tusb_config.h @@ -105,6 +105,7 @@ #define CFG_TUH_CDC 1 // CDC ACM #define CFG_TUH_CDC_FTDI 1 // FTDI Serial. FTDI is not part of CDC class, only to re-use CDC driver API #define CFG_TUH_CDC_CP210X 1 // CP210x Serial. CP210X is not part of CDC class, only to re-use CDC driver API +#define CFG_TUH_CDC_CH34X 1 // CH340 or CH341 Serial. CH34X is not part of CDC class, only to re-use CDC driver API #define CFG_TUH_HID (3*CFG_TUH_DEVICE_MAX) // typical keyboard + mouse device can have 3-4 HID interfaces #define CFG_TUH_MSC 1 #define CFG_TUH_VENDOR 0 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 c661f47be..bb7c3388d 100644 --- a/examples/host/cdc_msc_hid_freertos/src/tusb_config.h +++ b/examples/host/cdc_msc_hid_freertos/src/tusb_config.h @@ -110,6 +110,7 @@ #define CFG_TUH_CDC 1 // CDC ACM #define CFG_TUH_CDC_FTDI 1 // FTDI Serial. FTDI is not part of CDC class, only to re-use CDC driver API #define CFG_TUH_CDC_CP210X 1 // CP210x Serial. CP210X is not part of CDC class, only to re-use CDC driver API +#define CFG_TUH_CDC_CH34X 1 // CH340 or CH341 Serial. CH34X is not part of CDC class, only to re-use CDC driver API #define CFG_TUH_HID (3*CFG_TUH_DEVICE_MAX) // typical keyboard + mouse device can have 3-4 HID interfaces #define CFG_TUH_MSC 1 #define CFG_TUH_VENDOR 0 diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index a6dfb45ae..9b5186e0c 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -2,6 +2,7 @@ * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) + * Copyright (c) 2023 Heiko Kuester (CH34x support) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -69,7 +70,16 @@ typedef struct { uint8_t rx_ff_buf[CFG_TUH_CDC_TX_BUFSIZE]; CFG_TUH_MEM_ALIGN uint8_t rx_ep_buf[CFG_TUH_CDC_TX_EPSIZE]; } stream; - + #if CFG_TUH_CDC_CH34X + struct { + uint32_t baud_rate; + uint8_t mcr; + uint8_t msr; + uint8_t lcr; + uint32_t quirks; + uint8_t version; + } ch34x; + #endif } cdch_interface_t; CFG_TUH_MEM_SECTION @@ -121,6 +131,23 @@ static bool cp210x_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, static bool cp210x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data); #endif +//------------- CH34x prototypes -------------// +#if CFG_TUH_CDC_CH34X +#include "serial/ch34x.h" + +static uint16_t const ch34x_vids_pids[][2] = { CFG_TUH_CDC_CH34X_VID_PID_LIST }; +enum { + CH34X_VID_PID_COUNT = sizeof ( ch34x_vids_pids ) / sizeof ( ch34x_vids_pids[0] ) +}; + +static bool ch34x_open ( uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len ); +static void ch34x_process_config ( tuh_xfer_t* xfer ); + +static bool ch34x_set_modem_ctrl ( cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data ); +static bool ch34x_set_baudrate ( cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data ); +#endif + + enum { SERIAL_DRIVER_ACM = 0, @@ -131,6 +158,10 @@ enum { #if CFG_TUH_CDC_CP210X SERIAL_DRIVER_CP210X, #endif + +#if CFG_TUH_CDC_CH34X + SERIAL_DRIVER_CH34X, +#endif }; typedef struct { @@ -159,6 +190,13 @@ static const cdch_serial_driver_t serial_drivers[] = { .set_baudrate = cp210x_set_baudrate }, #endif + + #if CFG_TUH_CDC_CH34X + { .process_set_config = ch34x_process_config, + .set_control_line_state = ch34x_set_modem_ctrl, + .set_baudrate = ch34x_set_baudrate + }, +#endif }; enum { @@ -426,6 +464,12 @@ static void cdch_internal_control_complete(tuh_xfer_t* xfer) break; #endif + #if CFG_TUH_CDC_CH34X + case SERIAL_DRIVER_CH34X: + TU_ASSERT(false, ); // see special ch34x_control_complete function + break; + #endif + default: break; } } @@ -641,7 +685,7 @@ bool cdch_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const *itf_d { return acm_open(daddr, itf_desc, max_len); } - #if CFG_TUH_CDC_FTDI || CFG_TUH_CDC_CP210X + #if CFG_TUH_CDC_FTDI || CFG_TUH_CDC_CP210X || CFG_TUH_CDC_CH34X else if ( 0xff == itf_desc->bInterfaceClass ) { uint16_t vid, pid; @@ -666,8 +710,16 @@ bool cdch_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const *itf_d } } #endif + + #if CFG_TUH_CDC_CH34X + for (size_t i = 0; i < CH34X_VID_PID_COUNT; i++) { + if ( ch34x_vids_pids[i][0] == vid && ch34x_vids_pids[i][1] == pid ) { + return ch34x_open(daddr, itf_desc, max_len); + } + } + #endif } - #endif + #endif // CFG_TUH_CDC_FTDI || CFG_TUH_CDC_CP210X || CFG_TUH_CDC_CH34X return false; } @@ -1176,4 +1228,412 @@ static void cp210x_process_config(tuh_xfer_t* xfer) { #endif +//--------------------------------------------------------------------+ +// CH34x +//--------------------------------------------------------------------+ + +#if CFG_TUH_CDC_CH34X + +enum { + CONFIG_CH34X_STEP1 = 0, + CONFIG_CH34X_STEP2, + CONFIG_CH34X_STEP3, + CONFIG_CH34X_STEP4, + CONFIG_CH34X_STEP5, + CONFIG_CH34X_STEP6, + CONFIG_CH34X_STEP7, + CONFIG_CH34X_STEP8, + CONFIG_CH34X_COMPLETE +}; + +static bool ch34x_open ( uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len ) +{ + // CH34x Interface includes 1 vendor interface + 3 bulk endpoints + TU_VERIFY ( itf_desc->bNumEndpoints == 3 ); + TU_VERIFY ( sizeof ( tusb_desc_interface_t ) + 2 * sizeof ( tusb_desc_endpoint_t ) <= max_len ); + + cdch_interface_t *p_cdc = make_new_itf ( daddr, itf_desc ); + TU_VERIFY ( p_cdc ); + + TU_LOG_DRV ( "CH34x opened\r\n" ); + p_cdc->serial_drid = SERIAL_DRIVER_CH34X; + + // endpoint pair + tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const *) tu_desc_next ( itf_desc ); + + // data endpoints expected to be in pairs + return open_ep_stream_pair ( p_cdc, desc_ep ); +} + +static bool ch34x_set_request ( cdch_interface_t* p_cdc, uint8_t direction, uint8_t request, uint16_t value, uint16_t index, uint8_t* buffer, uint16_t length, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) +{ + tusb_control_request_t const request_setup = { + .bmRequestType_bit = { + .recipient = TUSB_REQ_RCPT_DEVICE, + .type = TUSB_REQ_TYPE_VENDOR, + .direction = direction + }, + .bRequest = request, + .wValue = tu_htole16 ( value ), + .wIndex = tu_htole16 ( index ), + .wLength = tu_htole16 ( length ) + }; + + // use usbh enum buf since application variable does not live long enough + uint8_t* enum_buf = NULL; + + if ( buffer && length > 0 ) { + enum_buf = usbh_get_enum_buf(); + tu_memcpy_s ( enum_buf, CFG_TUH_ENUMERATION_BUFSIZE, buffer, length ); + } + + tuh_xfer_t xfer = { + .daddr = p_cdc->daddr, + .ep_addr = 0, + .setup = &request_setup, + .buffer = enum_buf, + .complete_cb = complete_cb, + // CH34x needs a special handling of bInterfaceNumber, because wIndex is used for other purposes and not for bInterfaceNumber + .user_data = (uintptr_t)( ( p_cdc->bInterfaceNumber & 0xff ) << 8 ) | ( user_data & 0xff ) + }; + + return tuh_control_xfer ( &xfer ); + return false; +} + +static bool ch341_control_out ( cdch_interface_t* p_cdc, uint8_t request, uint16_t value, uint16_t index, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) +{ + return ch34x_set_request ( p_cdc, TUSB_DIR_OUT, request, value, index, /* buffer */ NULL, /* length */ 0, complete_cb, user_data ); +} + +static bool ch341_control_in ( cdch_interface_t* p_cdc, uint8_t request, uint16_t value, uint16_t index, uint8_t *buffer, uint16_t buffersize, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) +{ + return ch34x_set_request ( p_cdc, TUSB_DIR_IN, request, value, index, buffer, buffersize, complete_cb, user_data ); +} + +static int32_t ch341_write_reg ( cdch_interface_t* p_cdc, uint16_t reg, uint16_t value, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) +{ + return ch341_control_out ( p_cdc, CH341_REQ_WRITE_REG, /* value */ reg, /* index */ value, complete_cb, user_data ); +} + +static int32_t ch341_read_reg_request ( cdch_interface_t* p_cdc, uint16_t reg, uint8_t *buffer, uint16_t buffersize, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) +{ + return ch341_control_in ( p_cdc, CH341_REQ_READ_REG, reg, /* index */ 0, buffer, buffersize, complete_cb, user_data ); +} + +/* + * The device line speed is given by the following equation: + * + * baudrate = 48000000 / (2^(12 - 3 * ps - fact) * div), where + * + * 0 <= ps <= 3, + * 0 <= fact <= 1, + * 2 <= div <= 256 if fact = 0, or + * 9 <= div <= 256 if fact = 1 + */ +// calculate baudrate devisors +// Parts of this functions have been taken over from Linux driver /drivers/usb/serial/ch341.c +static int32_t ch341_get_divisor ( cdch_interface_t* p_cdc, uint32_t speed ) +{ + uint32_t fact, div, clk_div; + bool force_fact0 = false; + int32_t ps; + static const uint32_t ch341_min_rates[] = { + CH341_MIN_RATE(0), + CH341_MIN_RATE(1), + CH341_MIN_RATE(2), + CH341_MIN_RATE(3), + }; + + /* + * Clamp to supported range, this makes the (ps < 0) and (div < 2) + * sanity checks below redundant. + */ + inline uint32_t max ( uint32_t val, uint32_t maxval ) { return val > maxval ? val : maxval; } + inline uint32_t min ( uint32_t val, uint32_t minval ) { return val < minval ? val : minval; } + inline uint32_t clamp_val ( uint32_t val, uint32_t minval, uint32_t maxval ) { return min ( max ( val, minval ), maxval ); } + speed = clamp_val(speed, CH341_MIN_BPS, CH341_MAX_BPS); + + /* + * Start with highest possible base clock (fact = 1) that will give a + * divisor strictly less than 512. + */ + fact = 1; + for (ps = 3; ps >= 0; ps--) { + if (speed > ch341_min_rates[ps]) + break; + } + + if (ps < 0) + return -EINVAL; + + /* Determine corresponding divisor, rounding down. */ + clk_div = CH341_CLK_DIV(ps, fact); + div = CH341_CLKRATE / (clk_div * speed); + + /* Some devices require a lower base clock if ps < 3. */ + if (ps < 3 && (p_cdc->ch34x.quirks & CH341_QUIRK_LIMITED_PRESCALER)) + force_fact0 = true; + + /* Halve base clock (fact = 0) if required. */ + if (div < 9 || div > 255 || force_fact0) { + div /= 2; + clk_div *= 2; + fact = 0; + } + + if (div < 2) + return -EINVAL; + + /* + * Pick next divisor if resulting rate is closer to the requested one, + * scale up to avoid rounding errors on low rates. + */ + if (16 * CH341_CLKRATE / (clk_div * div) - 16 * speed >= + 16 * speed - 16 * CH341_CLKRATE / (clk_div * (div + 1))) + div++; + + /* + * Prefer lower base clock (fact = 0) if even divisor. + * + * Note that this makes the receiver more tolerant to errors. + */ + if (fact == 1 && div % 2 == 0) { + div /= 2; + fact = 0; + } + + return (0x100 - div) << 8 | fact << 2 | ps; +} + +// set baudrate (low level) +// do not confuse with ch34x_set_baudrate +// Parts of this functions have been taken over from Linux driver /drivers/usb/serial/ch341.c +static int32_t ch341_set_baudrate ( cdch_interface_t* p_cdc, uint32_t baud_rate, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) +{ + int val; + + if (!baud_rate) + return -EINVAL; + + val = ch341_get_divisor(p_cdc, baud_rate); + if (val < 0) + return -EINVAL; + + /* + * CH341A buffers data until a full endpoint-size packet (32 bytes) + * has been received unless bit 7 is set. + * + * At least one device with version 0x27 appears to have this bit + * inverted. + */ + if ( p_cdc->ch34x.version > 0x27 ) + val |= BIT(7); + + return ch341_write_reg ( p_cdc, CH341_REG_DIVISOR << 8 | CH341_REG_PRESCALER, val, complete_cb, user_data ); +} + +// set lcr register +// Parts of this functions have been taken over from Linux driver /drivers/usb/serial/ch341.c +static int32_t ch341_set_lcr ( cdch_interface_t* p_cdc, uint8_t lcr, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) +{ + /* + * Chip versions before version 0x30 as read using + * CH341_REQ_READ_VERSION used separate registers for line control + * (stop bits, parity and word length). Version 0x30 and above use + * CH341_REG_LCR only and CH341_REG_LCR2 is always set to zero. + */ + if ( p_cdc->ch34x.version < 0x30 ) + return 0; + + return ch341_write_reg ( p_cdc, CH341_REG_LCR2 << 8 | CH341_REG_LCR, lcr, complete_cb, user_data ); +} + +// set handshake (modem controls) +// Parts of this functions have been taken over from Linux driver /drivers/usb/serial/ch341.c +static int32_t ch341_set_handshake ( cdch_interface_t* p_cdc, uint8_t control, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) +{ + return ch341_control_out ( p_cdc, CH341_REQ_MODEM_CTRL, /* value */ ~control, /* index */ 0, complete_cb, user_data ); +} + +// detect quirks (special versions of CH34x) +// Parts of this functions have been taken over from Linux driver /drivers/usb/serial/ch341.c +static int32_t ch341_detect_quirks ( tuh_xfer_t* xfer, cdch_interface_t* p_cdc, uint8_t step, uint8_t *buffer, uint16_t buffersize, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) +{ + /* + * A subset of CH34x devices does not support all features. The + * prescaler is limited and there is no support for sending a RS232 + * break condition. A read failure when trying to set up the latter is + * used to detect these devices. + */ + switch ( step ) + { + case 1: + p_cdc->ch34x.quirks = 0; + return ch341_read_reg_request ( p_cdc, CH341_REG_BREAK, buffer, buffersize, complete_cb, user_data ); + break; + case 2: + if ( xfer->result != XFER_RESULT_SUCCESS ) + p_cdc->ch34x.quirks |= CH341_QUIRK_LIMITED_PRESCALER | CH341_QUIRK_SIMULATE_BREAK; + return true; + break; + default: + TU_ASSERT ( false ); // suspicious step + break; + } +} + +// internal control complete to update state such as line state, encoding +// CH34x needs a special interface recovery due to abnormal wIndex usage +static void ch34x_control_complete(tuh_xfer_t* xfer) +{ + uint8_t const itf_num = (uint8_t)( ( xfer->user_data & 0xff00 ) >> 8 ); + uint8_t const idx = tuh_cdc_itf_get_index ( xfer->daddr, itf_num ); + cdch_interface_t *p_cdc = get_itf ( idx ); + TU_ASSERT ( p_cdc, ); + TU_ASSERT ( p_cdc->serial_drid == SERIAL_DRIVER_CH34X, ); // ch34x_control_complete is only used for CH34x + + if (xfer->result == XFER_RESULT_SUCCESS) { + switch (xfer->setup->bRequest) { + case CH341_REQ_WRITE_REG: { // register write request + switch ( tu_le16toh ( xfer->setup->wValue ) ) { + case ( CH341_REG_DIVISOR << 8 | CH341_REG_PRESCALER ): { // baudrate write + p_cdc->line_coding.bit_rate = p_cdc->ch34x.baud_rate; + break; + } + default: { + TU_ASSERT(false, ); // unexpected register write + break; + } + } + break; + } + default: { + TU_ASSERT(false, ); // unexpected request + break; + } + } + xfer->complete_cb = p_cdc->user_control_cb; + if (xfer->complete_cb) + xfer->complete_cb(xfer); + } +} + +static bool ch34x_set_baudrate ( cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) // do not confuse with ch341_set_baudrate +{ + TU_LOG_DRV("CDC CH34x Set BaudRate = %lu\r\n", baudrate); + uint32_t baud_le = tu_htole32(baudrate); + p_cdc->ch34x.baud_rate = baudrate; + p_cdc->user_control_cb = complete_cb; + return ch341_set_baudrate ( p_cdc, baud_le, complete_cb ? ch34x_control_complete : NULL, user_data ); +} + +static bool ch34x_set_modem_ctrl ( cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) +{ + TU_LOG_DRV("CDC CH34x Set Control Line State\r\n"); + // todo later + return false; +} + +static void ch34x_process_config ( tuh_xfer_t* xfer ) +{ + uintptr_t const state = xfer->user_data & 0xff; + // CH34x needs a special handling of bInterfaceNumber, because wIndex is used for other purposes and not for bInterfaceNumber + uint8_t const itf_num = (uint8_t)( ( xfer->user_data & 0xff00 ) >> 8 ); + uint8_t const idx = tuh_cdc_itf_get_index ( xfer->daddr, itf_num ); + cdch_interface_t *p_cdc = get_itf ( idx ); + uint8_t buffer [ CH34X_BUFFER_SIZE ]; + cdc_line_coding_t line_coding = CFG_TUH_CDC_LINE_CODING_ON_ENUM; + TU_ASSERT ( p_cdc, ); + + if ( state == 0 ) { + // defaults + p_cdc->ch34x.baud_rate = DEFAULT_BAUD_RATE; + p_cdc->ch34x.mcr = 0; + p_cdc->ch34x.msr = 0; + p_cdc->ch34x.quirks = 0; + p_cdc->ch34x.version = 0; + /* + * Some CH340 devices appear unable to change the initial LCR + * settings, so set a sane 8N1 default. + */ + p_cdc->ch34x.lcr = CH341_LCR_ENABLE_RX | CH341_LCR_ENABLE_TX | CH341_LCR_CS8; + } + // This process flow has been taken over from Linux driver /drivers/usb/serial/ch341.c + switch ( state ) { + case CONFIG_CH34X_STEP1: // request version read + TU_ASSERT ( ch341_control_in ( p_cdc, /* request */ CH341_REQ_READ_VERSION, /* value */ 0, /* index */ 0, buffer, CH34X_BUFFER_SIZE, ch34x_process_config, CONFIG_CH34X_STEP2 ), ); + break; + case CONFIG_CH34X_STEP2: // handle version read data, request to init CH34x + p_cdc->ch34x.version = xfer->buffer[0]; + TU_LOG_DRV ( "Chip version=%02x\r\n", p_cdc->ch34x.version ); + TU_ASSERT ( ch341_control_out ( p_cdc, /* request */ CH341_REQ_SERIAL_INIT, /* value */ 0, /* index */ 0, ch34x_process_config, CONFIG_CH34X_STEP3 ), ); + break; + case CONFIG_CH34X_STEP3: // set baudrate with default values (see above) + TU_ASSERT ( ch341_set_baudrate ( p_cdc, p_cdc->ch34x.baud_rate, ch34x_process_config, CONFIG_CH34X_STEP4 ) > 0, ); + break; + case CONFIG_CH34X_STEP4: // set line controls with default values (see above) + TU_ASSERT ( ch341_set_lcr ( p_cdc, p_cdc->ch34x.lcr, ch34x_process_config, CONFIG_CH34X_STEP5 ) > 0, ); + break; + case CONFIG_CH34X_STEP5: // set handshake RTS/DTR + TU_ASSERT ( ch341_set_handshake ( p_cdc, p_cdc->ch34x.mcr, ch34x_process_config, CONFIG_CH34X_STEP6 ) > 0, ); + break; + case CONFIG_CH34X_STEP6: // detect quirks step 1 + TU_ASSERT ( ch341_detect_quirks ( xfer, p_cdc, /* step */ 1, buffer, CH34X_BUFFER_SIZE, ch34x_process_config, CONFIG_CH34X_STEP7 ) > 0, ); + break; + case CONFIG_CH34X_STEP7: // detect quirks step 2 and set baudrate with configured values + TU_ASSERT ( ch341_detect_quirks ( xfer, p_cdc, /* step */ 2, NULL, 0, NULL, 0 ) > 0, ); +#ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM + TU_ASSERT ( ch34x_set_baudrate ( p_cdc, line_coding.bit_rate, ch34x_process_config, CONFIG_CH34X_STEP8 ), ); +#else + TU_ATTR_FALLTHROUGH; #endif + break; + case CONFIG_CH34X_STEP8: // set data/stop bit quantities, parity +#ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM + p_cdc->ch34x.lcr = CH341_LCR_ENABLE_RX | CH341_LCR_ENABLE_TX; + switch ( line_coding.data_bits ) { + case 5: + p_cdc->ch34x.lcr |= CH341_LCR_CS5; + break; + case 6: + p_cdc->ch34x.lcr |= CH341_LCR_CS6; + break; + case 7: + p_cdc->ch34x.lcr |= CH341_LCR_CS7; + break; + case 8: + p_cdc->ch34x.lcr |= CH341_LCR_CS8; + break; + default: + TU_ASSERT ( false, ); // not supported data_bits + p_cdc->ch34x.lcr |= CH341_LCR_CS8; + break; + } + if ( line_coding.parity != CDC_LINE_CODING_PARITY_NONE ) { + p_cdc->ch34x.lcr |= CH341_LCR_ENABLE_PAR; + if ( line_coding.parity == CDC_LINE_CODING_PARITY_EVEN || line_coding.parity == CDC_LINE_CODING_PARITY_SPACE ) + p_cdc->ch34x.lcr |= CH341_LCR_PAR_EVEN; + if ( line_coding.parity == CDC_LINE_CODING_PARITY_MARK || line_coding.parity == CDC_LINE_CODING_PARITY_SPACE ) + p_cdc->ch34x.lcr |= CH341_LCR_MARK_SPACE; + } + TU_ASSERT ( line_coding.stop_bits == CDC_LINE_CODING_STOP_BITS_1 || line_coding.stop_bits == CDC_LINE_CODING_STOP_BITS_2, ); // not supported 1.5 stop bits + if ( line_coding.stop_bits == CDC_LINE_CODING_STOP_BITS_2 ) + p_cdc->ch34x.lcr |= CH341_LCR_STOP_BITS_2; + TU_ASSERT ( ch341_set_lcr ( p_cdc, p_cdc->ch34x.lcr, ch34x_process_config, CONFIG_CH34X_COMPLETE ) > 0, ); +#else + TU_ATTR_FALLTHROUGH; +#endif + break; + case CONFIG_CH34X_COMPLETE: + set_config_complete ( p_cdc, idx, itf_num ); + break; + default: + TU_ASSERT ( false, ); + break; + } +} + +#endif // CFG_TUH_CDC_CH34X + +#endif // (CFG_TUH_ENABLED && CFG_TUH_CDC) diff --git a/src/class/cdc/serial/ch34x.h b/src/class/cdc/serial/ch34x.h new file mode 100644 index 000000000..94e18b252 --- /dev/null +++ b/src/class/cdc/serial/ch34x.h @@ -0,0 +1,113 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2023 Heiko Kuester (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 _CH34X_H_ +#define _CH34X_H_ + +#include + +#define BIT(nr) ( (uint32_t)1 << (nr) ) + +#define CH34X_BUFFER_SIZE 2 + +// The following defines have been taken over from Linux driver /drivers/usb/serial/ch341.c + +#define DEFAULT_BAUD_RATE 9600 + +/* flags for IO-Bits */ +#define CH341_BIT_RTS (1 << 6) +#define CH341_BIT_DTR (1 << 5) + +/******************************/ +/* interrupt pipe definitions */ +/******************************/ +/* always 4 interrupt bytes */ +/* first irq byte normally 0x08 */ +/* second irq byte base 0x7d + below */ +/* third irq byte base 0x94 + below */ +/* fourth irq byte normally 0xee */ + +/* second interrupt byte */ +#define CH341_MULT_STAT 0x04 /* multiple status since last interrupt event */ + +/* status returned in third interrupt answer byte, inverted in data + from irq */ +#define CH341_BIT_CTS 0x01 +#define CH341_BIT_DSR 0x02 +#define CH341_BIT_RI 0x04 +#define CH341_BIT_DCD 0x08 +#define CH341_BITS_MODEM_STAT 0x0f /* all bits */ + +/* Break support - the information used to implement this was gleaned from + * the Net/FreeBSD uchcom.c driver by Takanori Watanabe. Domo arigato. + */ + +// USB requests +#define CH341_REQ_READ_VERSION 0x5F // dec 95 +#define CH341_REQ_WRITE_REG 0x9A +#define CH341_REQ_READ_REG 0x95 +#define CH341_REQ_SERIAL_INIT 0xA1 +#define CH341_REQ_MODEM_CTRL 0xA4 + +// CH34x registers +#define CH341_REG_BREAK 0x05 +#define CH341_REG_PRESCALER 0x12 +#define CH341_REG_DIVISOR 0x13 +#define CH341_REG_LCR 0x18 +#define CH341_REG_LCR2 0x25 + +#define CH341_NBREAK_BITS 0x01 + +// line control bits +#define CH341_LCR_ENABLE_RX 0x80 +#define CH341_LCR_ENABLE_TX 0x40 +#define CH341_LCR_MARK_SPACE 0x20 +#define CH341_LCR_PAR_EVEN 0x10 +#define CH341_LCR_ENABLE_PAR 0x08 +#define CH341_LCR_STOP_BITS_2 0x04 +#define CH341_LCR_CS8 0x03 +#define CH341_LCR_CS7 0x02 +#define CH341_LCR_CS6 0x01 +#define CH341_LCR_CS5 0x00 + +#define CH341_QUIRK_LIMITED_PRESCALER BIT(0) +#define CH341_QUIRK_SIMULATE_BREAK BIT(1) + +#define CH341_CLKRATE 48000000 +#define CH341_CLK_DIV(ps, fact) (1 << (12 - 3 * (ps) - (fact))) +#define CH341_MIN_RATE(ps) (CH341_CLKRATE / (CH341_CLK_DIV((ps), 1) * 512)) + +/* Supported range is 46 to 3000000 bps. */ +#define CH341_MIN_BPS DIV_ROUND_UP(CH341_CLKRATE, CH341_CLK_DIV(0, 0) * 256) +#define CH341_MAX_BPS (CH341_CLKRATE / (CH341_CLK_DIV(3, 0) * 2)) + +#define DIV_ROUND_UP __KERNEL_DIV_ROUND_UP +#define __KERNEL_DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) + +// error codes +#define EINVAL 22 /* Invalid argument */ + +#endif /* _CH34X_H_ */ diff --git a/src/tusb_option.h b/src/tusb_option.h index a76281c0c..13151a07b 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -470,6 +470,23 @@ 0xEA60, 0xEA70 #endif +#ifndef CFG_TUH_CDC_CH34X + // CH34X is not part of CDC class, only to re-use CDC driver API + #define CFG_TUH_CDC_CH34X 0 +#endif + +#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, 0x7523 }, /* ch340 chip */ \ + { 0x1a86, 0x7522 }, /* ch340k chip */ \ + { 0x1a86, 0x5523 }, /* ch341 chip */ \ + { 0x1a86, 0xe523 }, /* ch330 chip */ \ + { 0x4348, 0x5523 }, /* ch340 custom chip */ \ + { 0x2184, 0x0057 }, /* overtaken from Linux driver /drivers/usb/serial/ch341.c */ \ + { 0x9986, 0x7523 } /* overtaken from Linux driver /drivers/usb/serial/ch341.c */ +#endif + #ifndef CFG_TUH_HID #define CFG_TUH_HID 0 #endif From d92eb38c211899ed963250272d882fcac8dbaf9c Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 15 Jan 2024 16:56:18 +0700 Subject: [PATCH 046/454] change code style --- src/class/cdc/cdc_host.c | 528 +++++++++++++++++---------------------- 1 file changed, 236 insertions(+), 292 deletions(-) diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 4f36f7517..05a061487 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -106,7 +106,7 @@ static bool acm_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfe static uint16_t const ftdi_pids[] = { CFG_TUH_CDC_FTDI_PID_LIST }; enum { - FTDI_PID_COUNT = sizeof(ftdi_pids) / sizeof(ftdi_pids[0]) + FTDI_PID_COUNT = TU_ARRAY_SIZE(ftdi_pids) }; // Store last request baudrate since divisor to baudrate is not easy @@ -114,7 +114,6 @@ static uint32_t _ftdi_requested_baud; static bool ftdi_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len); static void ftdi_process_config(tuh_xfer_t* xfer); - static bool ftdi_sio_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data); static bool ftdi_sio_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data); #endif @@ -125,12 +124,11 @@ static bool ftdi_sio_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tu static uint16_t const cp210x_pids[] = { CFG_TUH_CDC_CP210X_PID_LIST }; enum { - CP210X_PID_COUNT = sizeof(cp210x_pids) / sizeof(cp210x_pids[0]) + CP210X_PID_COUNT = TU_ARRAY_SIZE(cp210x_pids) }; static bool cp210x_open(uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len); static void cp210x_process_config(tuh_xfer_t* xfer); - static bool cp210x_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data); static bool cp210x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data); #endif @@ -141,16 +139,16 @@ static bool cp210x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_ static uint16_t const ch34x_vids_pids[][2] = { CFG_TUH_CDC_CH34X_VID_PID_LIST }; enum { - CH34X_VID_PID_COUNT = sizeof ( ch34x_vids_pids ) / sizeof ( ch34x_vids_pids[0] ) + CH34X_VID_PID_COUNT = TU_ARRAY_SIZE(ch34x_vids_pids) }; static bool ch34x_open ( uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len ); static void ch34x_process_config ( tuh_xfer_t* xfer ); - static bool ch34x_set_modem_ctrl ( cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data ); static bool ch34x_set_baudrate ( cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data ); #endif +//------------- Common -------------// enum { SERIAL_DRIVER_ACM = 0, @@ -204,29 +202,25 @@ static const cdch_serial_driver_t serial_drivers[] = { }; enum { - SERIAL_DRIVER_COUNT = sizeof(serial_drivers) / sizeof(serial_drivers[0]) + SERIAL_DRIVER_COUNT = TU_ARRAY_SIZE(serial_drivers) }; //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ -static inline cdch_interface_t* get_itf(uint8_t idx) -{ +static inline cdch_interface_t* get_itf(uint8_t idx) { TU_ASSERT(idx < CFG_TUH_CDC, NULL); cdch_interface_t* p_cdc = &cdch_data[idx]; return (p_cdc->daddr != 0) ? p_cdc : NULL; } -static inline uint8_t get_idx_by_ep_addr(uint8_t daddr, uint8_t ep_addr) -{ - for(uint8_t i=0; idaddr == daddr) && - (ep_addr == p_cdc->ep_notif || ep_addr == p_cdc->stream.rx.ep_addr || ep_addr == p_cdc->stream.tx.ep_addr)) - { + (ep_addr == p_cdc->ep_notif || ep_addr == p_cdc->stream.rx.ep_addr || ep_addr == p_cdc->stream.tx.ep_addr)) { return i; } } @@ -234,14 +228,10 @@ static inline uint8_t get_idx_by_ep_addr(uint8_t daddr, uint8_t ep_addr) return TUSB_INDEX_INVALID_8; } - -static cdch_interface_t* make_new_itf(uint8_t daddr, tusb_desc_interface_t const *itf_desc) -{ - for(uint8_t i=0; idaddr = daddr; p_cdc->bInterfaceNumber = itf_desc->bInterfaceNumber; p_cdc->bInterfaceSubClass = itf_desc->bInterfaceSubClass; @@ -262,20 +252,16 @@ static void cdch_internal_control_complete(tuh_xfer_t* xfer); // APPLICATION API //--------------------------------------------------------------------+ -uint8_t tuh_cdc_itf_get_index(uint8_t daddr, uint8_t itf_num) -{ - for(uint8_t i=0; idaddr == daddr && p_cdc->bInterfaceNumber == itf_num) return i; } return TUSB_INDEX_INVALID_8; } -bool tuh_cdc_itf_get_info(uint8_t idx, tuh_itf_info_t* info) -{ +bool tuh_cdc_itf_get_info(uint8_t idx, tuh_itf_info_t* info) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc && info); @@ -297,30 +283,26 @@ bool tuh_cdc_itf_get_info(uint8_t idx, tuh_itf_info_t* info) return true; } -bool tuh_cdc_mounted(uint8_t idx) -{ +bool tuh_cdc_mounted(uint8_t idx) { cdch_interface_t* p_cdc = get_itf(idx); return p_cdc != NULL; } -bool tuh_cdc_get_dtr(uint8_t idx) -{ +bool tuh_cdc_get_dtr(uint8_t idx) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); return (p_cdc->line_state & CDC_CONTROL_LINE_STATE_DTR) ? true : false; } -bool tuh_cdc_get_rts(uint8_t idx) -{ +bool tuh_cdc_get_rts(uint8_t idx) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); return (p_cdc->line_state & CDC_CONTROL_LINE_STATE_RTS) ? true : false; } -bool tuh_cdc_get_local_line_coding(uint8_t idx, cdc_line_coding_t* line_coding) -{ +bool tuh_cdc_get_local_line_coding(uint8_t idx, cdc_line_coding_t* line_coding) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); @@ -333,32 +315,28 @@ bool tuh_cdc_get_local_line_coding(uint8_t idx, cdc_line_coding_t* line_coding) // Write //--------------------------------------------------------------------+ -uint32_t tuh_cdc_write(uint8_t idx, void const* buffer, uint32_t bufsize) -{ +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); } -uint32_t tuh_cdc_write_flush(uint8_t idx) -{ +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); } -bool tuh_cdc_write_clear(uint8_t idx) -{ +bool tuh_cdc_write_clear(uint8_t idx) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); return tu_edpt_stream_clear(&p_cdc->stream.tx); } -uint32_t tuh_cdc_write_available(uint8_t idx) -{ +uint32_t tuh_cdc_write_available(uint8_t idx) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); @@ -369,32 +347,28 @@ uint32_t tuh_cdc_write_available(uint8_t idx) // Read //--------------------------------------------------------------------+ -uint32_t tuh_cdc_read (uint8_t idx, void* buffer, uint32_t bufsize) -{ +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); } -uint32_t tuh_cdc_read_available(uint8_t idx) -{ +uint32_t tuh_cdc_read_available(uint8_t idx) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); return tu_edpt_stream_read_available(&p_cdc->stream.rx); } -bool tuh_cdc_peek(uint8_t idx, uint8_t* ch) -{ +bool tuh_cdc_peek(uint8_t idx, uint8_t* ch) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); return tu_edpt_stream_peek(&p_cdc->stream.rx, ch); } -bool tuh_cdc_read_clear (uint8_t idx) -{ +bool tuh_cdc_read_clear (uint8_t idx) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); @@ -408,15 +382,13 @@ bool tuh_cdc_read_clear (uint8_t idx) //--------------------------------------------------------------------+ // internal control complete to update state such as line state, encoding -static void cdch_internal_control_complete(tuh_xfer_t* xfer) -{ +static void cdch_internal_control_complete(tuh_xfer_t* xfer) { uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); uint8_t idx = tuh_cdc_itf_get_index(xfer->daddr, itf_num); cdch_interface_t* p_cdc = get_itf(idx); TU_ASSERT(p_cdc, ); - if (xfer->result == XFER_RESULT_SUCCESS) - { + if (xfer->result == XFER_RESULT_SUCCESS) { switch (p_cdc->serial_drid) { case SERIAL_DRIVER_ACM: switch (xfer->setup->bRequest) { @@ -502,7 +474,6 @@ bool tuh_cdc_set_control_line_state(uint8_t idx, uint16_t line_state, tuh_xfer_c } TU_VERIFY(ret && result == XFER_RESULT_SUCCESS); - p_cdc->line_state = (uint8_t) line_state; return true; } @@ -526,7 +497,6 @@ bool tuh_cdc_set_baudrate(uint8_t idx, uint32_t baudrate, tuh_xfer_cb_t complete } TU_VERIFY(ret && result == XFER_RESULT_SUCCESS); - p_cdc->line_coding.bit_rate = baudrate; return true; } @@ -552,7 +522,6 @@ bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding, } TU_VERIFY(ret && result == XFER_RESULT_SUCCESS); - p_cdc->line_coding = *line_coding; return true; } @@ -562,31 +531,26 @@ bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding, // CLASS-USBH API //--------------------------------------------------------------------+ -void cdch_init(void) -{ +void cdch_init(void) { tu_memclr(cdch_data, sizeof(cdch_data)); - for(size_t i=0; istream.tx, true, true, false, - p_cdc->stream.tx_ff_buf, CFG_TUH_CDC_TX_BUFSIZE, - p_cdc->stream.tx_ep_buf, CFG_TUH_CDC_TX_EPSIZE); + p_cdc->stream.tx_ff_buf, CFG_TUH_CDC_TX_BUFSIZE, + p_cdc->stream.tx_ep_buf, CFG_TUH_CDC_TX_EPSIZE); tu_edpt_stream_init(&p_cdc->stream.rx, true, false, false, - p_cdc->stream.rx_ff_buf, CFG_TUH_CDC_RX_BUFSIZE, - p_cdc->stream.rx_ep_buf, CFG_TUH_CDC_RX_EPSIZE); + p_cdc->stream.rx_ff_buf, CFG_TUH_CDC_RX_BUFSIZE, + p_cdc->stream.rx_ep_buf, CFG_TUH_CDC_RX_EPSIZE); } } -void cdch_close(uint8_t daddr) -{ - for(uint8_t idx=0; idxdaddr == daddr) - { + if (p_cdc->daddr == daddr) { TU_LOG_DRV(" CDCh close addr = %u index = %u\r\n", daddr, idx); // Invoke application callback @@ -618,16 +582,11 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t // - xferred_bytes is multiple of EP Packet size and not zero tu_edpt_stream_write_zlp_if_needed(&p_cdc->stream.tx, xferred_bytes); } - } - else if ( ep_addr == p_cdc->stream.rx.ep_addr ) { + } else if ( ep_addr == p_cdc->stream.rx.ep_addr ) { #if CFG_TUH_CDC_FTDI if (p_cdc->serial_drid == SERIAL_DRIVER_FTDI) { // FTDI reserve 2 bytes for status - // FTDI status -// uint8_t status[2] = { -// p_cdc->stream.rx.ep_buf[0], -// p_cdc->stream.rx.ep_buf[1] -// }; + // uint8_t status[2] = {p_cdc->stream.rx.ep_buf[0], p_cdc->stream.rx.ep_buf[1]}; tu_edpt_stream_read_xfer_complete_offset(&p_cdc->stream.rx, xferred_bytes, 2); }else #endif @@ -653,20 +612,15 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t // Enumeration //--------------------------------------------------------------------+ -static bool open_ep_stream_pair(cdch_interface_t* p_cdc, tusb_desc_endpoint_t const *desc_ep) -{ - for(size_t i=0; i<2; i++) - { +static bool open_ep_stream_pair(cdch_interface_t* p_cdc, tusb_desc_endpoint_t const* desc_ep) { + for (size_t i = 0; i < 2; i++) { TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && - TUSB_XFER_BULK == desc_ep->bmAttributes.xfer); - + TUSB_XFER_BULK == desc_ep->bmAttributes.xfer); TU_ASSERT(tuh_edpt_open(p_cdc->daddr, desc_ep)); - if ( tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN ) - { + if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { tu_edpt_stream_open(&p_cdc->stream.rx, p_cdc->daddr, desc_ep); - }else - { + } else { tu_edpt_stream_open(&p_cdc->stream.tx, p_cdc->daddr, desc_ep); } @@ -676,20 +630,17 @@ static bool open_ep_stream_pair(cdch_interface_t* p_cdc, tusb_desc_endpoint_t co return true; } -bool cdch_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len) -{ +bool cdch_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len) { (void) rhport; - // Only support ACM subclass + // For CDC: only support ACM subclass // Note: Protocol 0xFF can be RNDIS device - if ( TUSB_CLASS_CDC == itf_desc->bInterfaceClass && - CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass) - { + if (TUSB_CLASS_CDC == itf_desc->bInterfaceClass && + CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass) { return acm_open(daddr, itf_desc, max_len); } #if CFG_TUH_CDC_FTDI || CFG_TUH_CDC_CP210X || CFG_TUH_CDC_CH34X - else if ( TUSB_CLASS_VENDOR_SPECIFIC == itf_desc->bInterfaceClass ) - { + else if (TUSB_CLASS_VENDOR_SPECIFIC == itf_desc->bInterfaceClass) { uint16_t vid, pid; TU_VERIFY(tuh_vid_pid_get(daddr, &vid, &pid)); @@ -721,7 +672,7 @@ bool cdch_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const *itf_d } #endif } - #endif // CFG_TUH_CDC_FTDI || CFG_TUH_CDC_CP210X || CFG_TUH_CDC_CH34X + #endif return false; } @@ -767,94 +718,85 @@ enum { CONFIG_ACM_COMPLETE, }; -static bool acm_open(uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len) -{ - uint8_t const * p_desc_end = ((uint8_t const*) itf_desc) + max_len; +static bool acm_open(uint8_t daddr, tusb_desc_interface_t const* itf_desc, uint16_t max_len) { + uint8_t const* p_desc_end = ((uint8_t const*) itf_desc) + max_len; - cdch_interface_t * p_cdc = make_new_itf(daddr, itf_desc); + cdch_interface_t* p_cdc = make_new_itf(daddr, itf_desc); TU_VERIFY(p_cdc); p_cdc->serial_drid = SERIAL_DRIVER_ACM; //------------- Control Interface -------------// - uint8_t const * p_desc = tu_desc_next(itf_desc); + uint8_t const* p_desc = tu_desc_next(itf_desc); // Communication Functional Descriptors - while( (p_desc < p_desc_end) && (TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc)) ) - { - if ( CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT == cdc_functional_desc_typeof(p_desc) ) - { + while ((p_desc < p_desc_end) && (TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc))) { + if (CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT == cdc_functional_desc_typeof(p_desc)) { // save ACM bmCapabilities - p_cdc->acm_capability = ((cdc_desc_func_acm_t const *) p_desc)->bmCapabilities; + p_cdc->acm_capability = ((cdc_desc_func_acm_t const*) p_desc)->bmCapabilities; } p_desc = tu_desc_next(p_desc); } // Open notification endpoint of control interface if any - if (itf_desc->bNumEndpoints == 1) - { + if (itf_desc->bNumEndpoints == 1) { TU_ASSERT(TUSB_DESC_ENDPOINT == tu_desc_type(p_desc)); - 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( tuh_edpt_open(daddr, desc_ep) ); + TU_ASSERT(tuh_edpt_open(daddr, desc_ep)); p_cdc->ep_notif = desc_ep->bEndpointAddress; 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 p_desc = tu_desc_next(p_desc); // data endpoints expected to be in pairs - TU_ASSERT(open_ep_stream_pair(p_cdc, (tusb_desc_endpoint_t const *) p_desc)); + TU_ASSERT(open_ep_stream_pair(p_cdc, (tusb_desc_endpoint_t const*) p_desc)); } return true; } -static void acm_process_config(tuh_xfer_t* xfer) -{ +static void acm_process_config(tuh_xfer_t* xfer) { uintptr_t const state = xfer->user_data; uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); uint8_t const idx = tuh_cdc_itf_get_index(xfer->daddr, itf_num); - cdch_interface_t * p_cdc = get_itf(idx); - TU_ASSERT(p_cdc, ); + cdch_interface_t* p_cdc = get_itf(idx); + TU_ASSERT(p_cdc,); - switch(state) - { + switch (state) { case CONFIG_ACM_SET_CONTROL_LINE_STATE: #if CFG_TUH_CDC_LINE_CONTROL_ON_ENUM - if (p_cdc->acm_capability.support_line_request) - { - TU_ASSERT(acm_set_control_line_state(p_cdc, CFG_TUH_CDC_LINE_CONTROL_ON_ENUM, acm_process_config, - CONFIG_ACM_SET_LINE_CODING), ); + if (p_cdc->acm_capability.support_line_request) { + TU_ASSERT(acm_set_control_line_state(p_cdc, CFG_TUH_CDC_LINE_CONTROL_ON_ENUM, acm_process_config, CONFIG_ACM_SET_LINE_CODING),); break; } - #endif + #endif TU_ATTR_FALLTHROUGH; case CONFIG_ACM_SET_LINE_CODING: - #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM - if (p_cdc->acm_capability.support_line_request) - { + #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM + if (p_cdc->acm_capability.support_line_request) { cdc_line_coding_t line_coding = CFG_TUH_CDC_LINE_CODING_ON_ENUM; - TU_ASSERT(acm_set_line_coding(p_cdc, &line_coding, acm_process_config, CONFIG_ACM_COMPLETE), ); + TU_ASSERT(acm_set_line_coding(p_cdc, &line_coding, acm_process_config, CONFIG_ACM_COMPLETE),); break; } - #endif + #endif TU_ATTR_FALLTHROUGH; case CONFIG_ACM_COMPLETE: // itf_num+1 to account for data interface as well - set_config_complete(p_cdc, idx, itf_num+1); + set_config_complete(p_cdc, idx, itf_num + 1); break; - default: break; + default: + break; } } @@ -987,13 +929,12 @@ static bool ftdi_sio_set_request(cdch_interface_t* p_cdc, uint8_t command, uint1 return tuh_control_xfer(&xfer); } -static bool ftdi_sio_reset(cdch_interface_t* p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ +static bool ftdi_sio_reset(cdch_interface_t* p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return ftdi_sio_set_request(p_cdc, FTDI_SIO_RESET, FTDI_SIO_RESET_SIO, complete_cb, user_data); } -static bool ftdi_sio_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ +static bool +ftdi_sio_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { TU_LOG_DRV("CDC FTDI Set Control Line State\r\n"); p_cdc->user_control_cb = complete_cb; TU_ASSERT(ftdi_sio_set_request(p_cdc, FTDI_SIO_MODEM_CTRL, 0x0300 | line_state, @@ -1001,8 +942,7 @@ static bool ftdi_sio_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state return true; } -static uint32_t ftdi_232bm_baud_base_to_divisor(uint32_t baud, uint32_t base) -{ +static uint32_t ftdi_232bm_baud_base_to_divisor(uint32_t baud, uint32_t base) { const uint8_t divfrac[8] = { 0, 3, 2, 4, 1, 5, 6, 7 }; uint32_t divisor; @@ -1022,13 +962,11 @@ static uint32_t ftdi_232bm_baud_base_to_divisor(uint32_t baud, uint32_t base) return divisor; } -static uint32_t ftdi_232bm_baud_to_divisor(uint32_t baud) -{ +static uint32_t ftdi_232bm_baud_to_divisor(uint32_t baud) { return ftdi_232bm_baud_base_to_divisor(baud, 48000000u); } -static bool ftdi_sio_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ +static bool ftdi_sio_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { uint16_t const divisor = (uint16_t) ftdi_232bm_baud_to_divisor(baudrate); TU_LOG_DRV("CDC FTDI Set BaudRate = %lu, divisor = 0x%04x\r\n", baudrate, divisor); @@ -1055,8 +993,7 @@ static void ftdi_process_config(tuh_xfer_t* xfer) { case CONFIG_FTDI_MODEM_CTRL: #if CFG_TUH_CDC_LINE_CONTROL_ON_ENUM - TU_ASSERT( - ftdi_sio_set_modem_ctrl(p_cdc, CFG_TUH_CDC_LINE_CONTROL_ON_ENUM, ftdi_process_config, CONFIG_FTDI_SET_BAUDRATE),); + TU_ASSERT(ftdi_sio_set_modem_ctrl(p_cdc, CFG_TUH_CDC_LINE_CONTROL_ON_ENUM, ftdi_process_config, CONFIG_FTDI_SET_BAUDRATE),); break; #else TU_ATTR_FALLTHROUGH; @@ -1172,8 +1109,7 @@ static bool cp210x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_ complete_cb ? cdch_internal_control_complete : NULL, user_data); } -static bool cp210x_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ +static bool cp210x_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { TU_LOG_DRV("CDC CP210x Set Control Line State\r\n"); p_cdc->user_control_cb = complete_cb; return cp210x_set_request(p_cdc, CP210X_SET_MHS, 0x0300 | line_state, NULL, 0, @@ -1213,8 +1149,7 @@ static void cp210x_process_config(tuh_xfer_t* xfer) { case CONFIG_CP210X_SET_DTR_RTS: #if CFG_TUH_CDC_LINE_CONTROL_ON_ENUM - TU_ASSERT( - cp210x_set_modem_ctrl(p_cdc, CFG_TUH_CDC_LINE_CONTROL_ON_ENUM, cp210x_process_config, CONFIG_CP210X_COMPLETE),); + TU_ASSERT(cp210x_set_modem_ctrl(p_cdc, CFG_TUH_CDC_LINE_CONTROL_ON_ENUM, cp210x_process_config, CONFIG_CP210X_COMPLETE),); break; #else TU_ATTR_FALLTHROUGH; @@ -1248,8 +1183,7 @@ enum { CONFIG_CH34X_COMPLETE }; -static bool ch34x_open ( uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len ) -{ +static bool ch34x_open ( uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len ) { // CH34x Interface includes 1 vendor interface + 3 bulk endpoints TU_VERIFY ( itf_desc->bNumEndpoints == 3 ); TU_VERIFY ( sizeof ( tusb_desc_interface_t ) + 2 * sizeof ( tusb_desc_endpoint_t ) <= max_len ); @@ -1303,23 +1237,19 @@ static bool ch34x_set_request ( cdch_interface_t* p_cdc, uint8_t direction, uint return false; } -static bool ch341_control_out ( cdch_interface_t* p_cdc, uint8_t request, uint16_t value, uint16_t index, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) -{ +static bool ch341_control_out ( cdch_interface_t* p_cdc, uint8_t request, uint16_t value, uint16_t index, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) { return ch34x_set_request ( p_cdc, TUSB_DIR_OUT, request, value, index, /* buffer */ NULL, /* length */ 0, complete_cb, user_data ); } -static bool ch341_control_in ( cdch_interface_t* p_cdc, uint8_t request, uint16_t value, uint16_t index, uint8_t *buffer, uint16_t buffersize, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) -{ +static bool ch341_control_in ( cdch_interface_t* p_cdc, uint8_t request, uint16_t value, uint16_t index, uint8_t *buffer, uint16_t buffersize, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) { return ch34x_set_request ( p_cdc, TUSB_DIR_IN, request, value, index, buffer, buffersize, complete_cb, user_data ); } -static int32_t ch341_write_reg ( cdch_interface_t* p_cdc, uint16_t reg, uint16_t value, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) -{ +static int32_t ch341_write_reg ( cdch_interface_t* p_cdc, uint16_t reg, uint16_t value, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) { return ch341_control_out ( p_cdc, CH341_REQ_WRITE_REG, /* value */ reg, /* index */ value, complete_cb, user_data ); } -static int32_t ch341_read_reg_request ( cdch_interface_t* p_cdc, uint16_t reg, uint8_t *buffer, uint16_t buffersize, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) -{ +static int32_t ch341_read_reg_request ( cdch_interface_t* p_cdc, uint16_t reg, uint8_t *buffer, uint16_t buffersize, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) { return ch341_control_in ( p_cdc, CH341_REQ_READ_REG, reg, /* index */ 0, buffer, buffersize, complete_cb, user_data ); } @@ -1335,8 +1265,7 @@ static int32_t ch341_read_reg_request ( cdch_interface_t* p_cdc, uint16_t reg, u */ // calculate baudrate devisors // Parts of this functions have been taken over from Linux driver /drivers/usb/serial/ch341.c -static int32_t ch341_get_divisor ( cdch_interface_t* p_cdc, uint32_t speed ) -{ +static int32_t ch341_get_divisor ( cdch_interface_t* p_cdc, uint32_t speed ) { uint32_t fact, div, clk_div; bool force_fact0 = false; int32_t ps; @@ -1362,20 +1291,19 @@ static int32_t ch341_get_divisor ( cdch_interface_t* p_cdc, uint32_t speed ) */ fact = 1; for (ps = 3; ps >= 0; ps--) { - if (speed > ch341_min_rates[ps]) - break; + if (speed > ch341_min_rates[ps]) break; } - if (ps < 0) - return -EINVAL; + if (ps < 0) return -EINVAL; /* Determine corresponding divisor, rounding down. */ clk_div = CH341_CLK_DIV(ps, fact); div = CH341_CLKRATE / (clk_div * speed); /* Some devices require a lower base clock if ps < 3. */ - if (ps < 3 && (p_cdc->ch34x.quirks & CH341_QUIRK_LIMITED_PRESCALER)) + if (ps < 3 && (p_cdc->ch34x.quirks & CH341_QUIRK_LIMITED_PRESCALER)) { force_fact0 = true; + } /* Halve base clock (fact = 0) if required. */ if (div < 9 || div > 255 || force_fact0) { @@ -1384,16 +1312,16 @@ static int32_t ch341_get_divisor ( cdch_interface_t* p_cdc, uint32_t speed ) fact = 0; } - if (div < 2) - return -EINVAL; + if (div < 2) return -EINVAL; /* * Pick next divisor if resulting rate is closer to the requested one, * scale up to avoid rounding errors on low rates. */ if (16 * CH341_CLKRATE / (clk_div * div) - 16 * speed >= - 16 * speed - 16 * CH341_CLKRATE / (clk_div * (div + 1))) + 16 * speed - 16 * CH341_CLKRATE / (clk_div * (div + 1))) { div++; + } /* * Prefer lower base clock (fact = 0) if even divisor. @@ -1411,16 +1339,13 @@ static int32_t ch341_get_divisor ( cdch_interface_t* p_cdc, uint32_t speed ) // set baudrate (low level) // do not confuse with ch34x_set_baudrate // Parts of this functions have been taken over from Linux driver /drivers/usb/serial/ch341.c -static int32_t ch341_set_baudrate ( cdch_interface_t* p_cdc, uint32_t baud_rate, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) -{ +static int32_t ch341_set_baudrate ( cdch_interface_t* p_cdc, uint32_t baud_rate, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) { int val; - if (!baud_rate) - return -EINVAL; + if (!baud_rate) return -EINVAL; val = ch341_get_divisor(p_cdc, baud_rate); - if (val < 0) - return -EINVAL; + if (val < 0) return -EINVAL; /* * CH341A buffers data until a full endpoint-size packet (32 bytes) @@ -1429,100 +1354,94 @@ static int32_t ch341_set_baudrate ( cdch_interface_t* p_cdc, uint32_t baud_rate, * At least one device with version 0x27 appears to have this bit * inverted. */ - if ( p_cdc->ch34x.version > 0x27 ) + if ( p_cdc->ch34x.version > 0x27 ) { val |= BIT(7); + } return ch341_write_reg ( p_cdc, CH341_REG_DIVISOR << 8 | CH341_REG_PRESCALER, val, complete_cb, user_data ); } // set lcr register // Parts of this functions have been taken over from Linux driver /drivers/usb/serial/ch341.c -static int32_t ch341_set_lcr ( cdch_interface_t* p_cdc, uint8_t lcr, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) -{ +static int32_t ch341_set_lcr ( cdch_interface_t* p_cdc, uint8_t lcr, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) { /* * Chip versions before version 0x30 as read using * CH341_REQ_READ_VERSION used separate registers for line control * (stop bits, parity and word length). Version 0x30 and above use * CH341_REG_LCR only and CH341_REG_LCR2 is always set to zero. */ - if ( p_cdc->ch34x.version < 0x30 ) - return 0; + if ( p_cdc->ch34x.version < 0x30 ) return 0; return ch341_write_reg ( p_cdc, CH341_REG_LCR2 << 8 | CH341_REG_LCR, lcr, complete_cb, user_data ); } // set handshake (modem controls) // Parts of this functions have been taken over from Linux driver /drivers/usb/serial/ch341.c -static int32_t ch341_set_handshake ( cdch_interface_t* p_cdc, uint8_t control, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) -{ +static int32_t ch341_set_handshake ( cdch_interface_t* p_cdc, uint8_t control, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) { return ch341_control_out ( p_cdc, CH341_REQ_MODEM_CTRL, /* value */ ~control, /* index */ 0, complete_cb, user_data ); } // detect quirks (special versions of CH34x) // Parts of this functions have been taken over from Linux driver /drivers/usb/serial/ch341.c -static int32_t ch341_detect_quirks ( tuh_xfer_t* xfer, cdch_interface_t* p_cdc, uint8_t step, uint8_t *buffer, uint16_t buffersize, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) -{ +static int32_t ch341_detect_quirks ( tuh_xfer_t* xfer, cdch_interface_t* p_cdc, uint8_t step, uint8_t *buffer, uint16_t buffersize, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) { /* * A subset of CH34x devices does not support all features. The * prescaler is limited and there is no support for sending a RS232 * break condition. A read failure when trying to set up the latter is * used to detect these devices. */ - switch ( step ) - { - case 1: - p_cdc->ch34x.quirks = 0; - return ch341_read_reg_request ( p_cdc, CH341_REG_BREAK, buffer, buffersize, complete_cb, user_data ); - break; - case 2: - if ( xfer->result != XFER_RESULT_SUCCESS ) - p_cdc->ch34x.quirks |= CH341_QUIRK_LIMITED_PRESCALER | CH341_QUIRK_SIMULATE_BREAK; - return true; - break; - default: - TU_ASSERT ( false ); // suspicious step - break; + switch (step) { + case 1: + p_cdc->ch34x.quirks = 0; + return ch341_read_reg_request(p_cdc, CH341_REG_BREAK, buffer, buffersize, complete_cb, user_data); + break; + + case 2: + if (xfer->result != XFER_RESULT_SUCCESS) { + p_cdc->ch34x.quirks |= CH341_QUIRK_LIMITED_PRESCALER | CH341_QUIRK_SIMULATE_BREAK; + } + return true; + break; + + default: + TU_ASSERT (false); // suspicious step + break; } } // internal control complete to update state such as line state, encoding // CH34x needs a special interface recovery due to abnormal wIndex usage -static void ch34x_control_complete(tuh_xfer_t* xfer) -{ - uint8_t const itf_num = (uint8_t)( ( xfer->user_data & 0xff00 ) >> 8 ); - uint8_t const idx = tuh_cdc_itf_get_index ( xfer->daddr, itf_num ); - cdch_interface_t *p_cdc = get_itf ( idx ); - TU_ASSERT ( p_cdc, ); - TU_ASSERT ( p_cdc->serial_drid == SERIAL_DRIVER_CH34X, ); // ch34x_control_complete is only used for CH34x +static void ch34x_control_complete(tuh_xfer_t* xfer) { + uint8_t const itf_num = (uint8_t) ((xfer->user_data & 0xff00) >> 8); + uint8_t const idx = tuh_cdc_itf_get_index(xfer->daddr, itf_num); + cdch_interface_t* p_cdc = get_itf(idx); + TU_ASSERT (p_cdc,); + TU_ASSERT (p_cdc->serial_drid == SERIAL_DRIVER_CH34X,); // ch34x_control_complete is only used for CH34x if (xfer->result == XFER_RESULT_SUCCESS) { switch (xfer->setup->bRequest) { - case CH341_REQ_WRITE_REG: { // register write request - switch ( tu_le16toh ( xfer->setup->wValue ) ) { - case ( CH341_REG_DIVISOR << 8 | CH341_REG_PRESCALER ): { // baudrate write - p_cdc->line_coding.bit_rate = p_cdc->ch34x.baud_rate; + case CH341_REQ_WRITE_REG: // register write request + switch (tu_le16toh (xfer->setup->wValue)) { + case (CH341_REG_DIVISOR << 8 | CH341_REG_PRESCALER): // baudrate write + p_cdc->line_coding.bit_rate = p_cdc->ch34x.baud_rate; + break; + + default: + TU_ASSERT(false,); // unexpected register write + break; + } break; - } - default: { - TU_ASSERT(false, ); // unexpected register write + + default: + TU_ASSERT(false,); // unexpected request break; - } - } - break; - } - default: { - TU_ASSERT(false, ); // unexpected request - break; - } } xfer->complete_cb = p_cdc->user_control_cb; - if (xfer->complete_cb) - xfer->complete_cb(xfer); + if (xfer->complete_cb) xfer->complete_cb(xfer); } } -static bool ch34x_set_baudrate ( cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) // do not confuse with ch341_set_baudrate -{ +static bool ch34x_set_baudrate ( cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) /* do not confuse with ch341_set_baudrate */ { TU_LOG_DRV("CDC CH34x Set BaudRate = %lu\r\n", baudrate); uint32_t baud_le = tu_htole32(baudrate); p_cdc->ch34x.baud_rate = baudrate; @@ -1530,15 +1449,13 @@ static bool ch34x_set_baudrate ( cdch_interface_t* p_cdc, uint32_t baudrate, tuh return ch341_set_baudrate ( p_cdc, baud_le, complete_cb ? ch34x_control_complete : NULL, user_data ); } -static bool ch34x_set_modem_ctrl ( cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) -{ +static bool ch34x_set_modem_ctrl ( cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) { TU_LOG_DRV("CDC CH34x Set Control Line State\r\n"); // todo later return false; } -static void ch34x_process_config ( tuh_xfer_t* xfer ) -{ +static void ch34x_process_config ( tuh_xfer_t* xfer ) { uintptr_t const state = xfer->user_data & 0xff; // CH34x needs a special handling of bInterfaceNumber, because wIndex is used for other purposes and not for bInterfaceNumber uint8_t const itf_num = (uint8_t)( ( xfer->user_data & 0xff00 ) >> 8 ); @@ -1561,81 +1478,108 @@ static void ch34x_process_config ( tuh_xfer_t* xfer ) */ p_cdc->ch34x.lcr = CH341_LCR_ENABLE_RX | CH341_LCR_ENABLE_TX | CH341_LCR_CS8; } + // This process flow has been taken over from Linux driver /drivers/usb/serial/ch341.c - switch ( state ) { - case CONFIG_CH34X_STEP1: // request version read - TU_ASSERT ( ch341_control_in ( p_cdc, /* request */ CH341_REQ_READ_VERSION, /* value */ 0, /* index */ 0, buffer, CH34X_BUFFER_SIZE, ch34x_process_config, CONFIG_CH34X_STEP2 ), ); - break; - case CONFIG_CH34X_STEP2: // handle version read data, request to init CH34x - p_cdc->ch34x.version = xfer->buffer[0]; - TU_LOG_DRV ( "Chip version=%02x\r\n", p_cdc->ch34x.version ); - TU_ASSERT ( ch341_control_out ( p_cdc, /* request */ CH341_REQ_SERIAL_INIT, /* value */ 0, /* index */ 0, ch34x_process_config, CONFIG_CH34X_STEP3 ), ); - break; - case CONFIG_CH34X_STEP3: // set baudrate with default values (see above) - TU_ASSERT ( ch341_set_baudrate ( p_cdc, p_cdc->ch34x.baud_rate, ch34x_process_config, CONFIG_CH34X_STEP4 ) > 0, ); - break; - case CONFIG_CH34X_STEP4: // set line controls with default values (see above) - TU_ASSERT ( ch341_set_lcr ( p_cdc, p_cdc->ch34x.lcr, ch34x_process_config, CONFIG_CH34X_STEP5 ) > 0, ); - break; - case CONFIG_CH34X_STEP5: // set handshake RTS/DTR - TU_ASSERT ( ch341_set_handshake ( p_cdc, p_cdc->ch34x.mcr, ch34x_process_config, CONFIG_CH34X_STEP6 ) > 0, ); - break; - case CONFIG_CH34X_STEP6: // detect quirks step 1 - TU_ASSERT ( ch341_detect_quirks ( xfer, p_cdc, /* step */ 1, buffer, CH34X_BUFFER_SIZE, ch34x_process_config, CONFIG_CH34X_STEP7 ) > 0, ); - break; - case CONFIG_CH34X_STEP7: // detect quirks step 2 and set baudrate with configured values - TU_ASSERT ( ch341_detect_quirks ( xfer, p_cdc, /* step */ 2, NULL, 0, NULL, 0 ) > 0, ); + switch (state) { + case CONFIG_CH34X_STEP1: // request version read + TU_ASSERT (ch341_control_in(p_cdc, /* request */ CH341_REQ_READ_VERSION, /* value */ 0, /* index */0, + buffer, CH34X_BUFFER_SIZE, ch34x_process_config, CONFIG_CH34X_STEP2),); + break; + + case CONFIG_CH34X_STEP2: // handle version read data, request to init CH34x + p_cdc->ch34x.version = xfer->buffer[0]; + TU_LOG_DRV ("Chip version=%02x\r\n", p_cdc->ch34x.version); + TU_ASSERT (ch341_control_out(p_cdc, /* request */ CH341_REQ_SERIAL_INIT, /* value */ 0, /* index */0, + ch34x_process_config, CONFIG_CH34X_STEP3),); + break; + + case CONFIG_CH34X_STEP3: // set baudrate with default values (see above) + TU_ASSERT (ch341_set_baudrate(p_cdc, p_cdc->ch34x.baud_rate, ch34x_process_config, + CONFIG_CH34X_STEP4) > 0,); + break; + + case CONFIG_CH34X_STEP4: // set line controls with default values (see above) + TU_ASSERT (ch341_set_lcr(p_cdc, p_cdc->ch34x.lcr, ch34x_process_config, CONFIG_CH34X_STEP5) > 0,); + break; + + case CONFIG_CH34X_STEP5: // set handshake RTS/DTR + TU_ASSERT (ch341_set_handshake(p_cdc, p_cdc->ch34x.mcr, ch34x_process_config, CONFIG_CH34X_STEP6) > 0,); + break; + + case CONFIG_CH34X_STEP6: // detect quirks step 1 + TU_ASSERT (ch341_detect_quirks(xfer, p_cdc, /* step */ 1, buffer, CH34X_BUFFER_SIZE, + ch34x_process_config, CONFIG_CH34X_STEP7) > 0,); + break; + + case CONFIG_CH34X_STEP7: // detect quirks step 2 and set baudrate with configured values + TU_ASSERT (ch341_detect_quirks(xfer, p_cdc, /* step */ 2, NULL, 0, NULL, 0) > 0,); #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM - TU_ASSERT ( ch34x_set_baudrate ( p_cdc, line_coding.bit_rate, ch34x_process_config, CONFIG_CH34X_STEP8 ), ); + TU_ASSERT (ch34x_set_baudrate(p_cdc, line_coding.bit_rate, ch34x_process_config, CONFIG_CH34X_STEP8),); #else - TU_ATTR_FALLTHROUGH; + TU_ATTR_FALLTHROUGH; #endif - break; - case CONFIG_CH34X_STEP8: // set data/stop bit quantities, parity + break; + + case CONFIG_CH34X_STEP8: // set data/stop bit quantities, parity #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM - p_cdc->ch34x.lcr = CH341_LCR_ENABLE_RX | CH341_LCR_ENABLE_TX; - switch ( line_coding.data_bits ) { - case 5: - p_cdc->ch34x.lcr |= CH341_LCR_CS5; - break; - case 6: - p_cdc->ch34x.lcr |= CH341_LCR_CS6; - break; - case 7: - p_cdc->ch34x.lcr |= CH341_LCR_CS7; - break; - case 8: - p_cdc->ch34x.lcr |= CH341_LCR_CS8; - break; - default: - TU_ASSERT ( false, ); // not supported data_bits - p_cdc->ch34x.lcr |= CH341_LCR_CS8; - break; - } - if ( line_coding.parity != CDC_LINE_CODING_PARITY_NONE ) { - p_cdc->ch34x.lcr |= CH341_LCR_ENABLE_PAR; - if ( line_coding.parity == CDC_LINE_CODING_PARITY_EVEN || line_coding.parity == CDC_LINE_CODING_PARITY_SPACE ) - p_cdc->ch34x.lcr |= CH341_LCR_PAR_EVEN; - if ( line_coding.parity == CDC_LINE_CODING_PARITY_MARK || line_coding.parity == CDC_LINE_CODING_PARITY_SPACE ) - p_cdc->ch34x.lcr |= CH341_LCR_MARK_SPACE; - } - TU_ASSERT ( line_coding.stop_bits == CDC_LINE_CODING_STOP_BITS_1 || line_coding.stop_bits == CDC_LINE_CODING_STOP_BITS_2, ); // not supported 1.5 stop bits - if ( line_coding.stop_bits == CDC_LINE_CODING_STOP_BITS_2 ) - p_cdc->ch34x.lcr |= CH341_LCR_STOP_BITS_2; - TU_ASSERT ( ch341_set_lcr ( p_cdc, p_cdc->ch34x.lcr, ch34x_process_config, CONFIG_CH34X_COMPLETE ) > 0, ); + p_cdc->ch34x.lcr = CH341_LCR_ENABLE_RX | CH341_LCR_ENABLE_TX; + switch (line_coding.data_bits) { + case 5: + p_cdc->ch34x.lcr |= CH341_LCR_CS5; + break; + + case 6: + p_cdc->ch34x.lcr |= CH341_LCR_CS6; + break; + + case 7: + p_cdc->ch34x.lcr |= CH341_LCR_CS7; + break; + + case 8: + p_cdc->ch34x.lcr |= CH341_LCR_CS8; + break; + + default: + TU_ASSERT (false,); // not supported data_bits + p_cdc->ch34x.lcr |= CH341_LCR_CS8; + break; + } + + if (line_coding.parity != CDC_LINE_CODING_PARITY_NONE) { + p_cdc->ch34x.lcr |= CH341_LCR_ENABLE_PAR; + + if (line_coding.parity == CDC_LINE_CODING_PARITY_EVEN || + line_coding.parity == CDC_LINE_CODING_PARITY_SPACE) { + p_cdc->ch34x.lcr |= CH341_LCR_PAR_EVEN; + } + + if (line_coding.parity == CDC_LINE_CODING_PARITY_MARK || + line_coding.parity == CDC_LINE_CODING_PARITY_SPACE) { + p_cdc->ch34x.lcr |= CH341_LCR_MARK_SPACE; + } + } + TU_ASSERT (line_coding.stop_bits == CDC_LINE_CODING_STOP_BITS_1 || line_coding.stop_bits == + CDC_LINE_CODING_STOP_BITS_2,); // not supported 1.5 stop bits + if (line_coding.stop_bits == CDC_LINE_CODING_STOP_BITS_2) { + p_cdc->ch34x.lcr |= CH341_LCR_STOP_BITS_2; + } + TU_ASSERT (ch341_set_lcr(p_cdc, p_cdc->ch34x.lcr, ch34x_process_config, CONFIG_CH34X_COMPLETE) > 0,); #else - TU_ATTR_FALLTHROUGH; + TU_ATTR_FALLTHROUGH; #endif - break; + break; + case CONFIG_CH34X_COMPLETE: - set_config_complete ( p_cdc, idx, itf_num ); + set_config_complete(p_cdc, idx, itf_num); break; + default: - TU_ASSERT ( false, ); + TU_ASSERT (false,); break; } } #endif // CFG_TUH_CDC_CH34X -#endif // (CFG_TUH_ENABLED && CFG_TUH_CDC) +#endif From d192868d62b56ef2eab9300bf0698a77e4e01cd3 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 15 Jan 2024 18:25:15 +0700 Subject: [PATCH 047/454] fix sign-conversion warning --- src/class/cdc/cdc_host.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 05a061487..0cc35da52 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -1207,7 +1207,7 @@ static bool ch34x_set_request ( cdch_interface_t* p_cdc, uint8_t direction, uint .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_DEVICE, .type = TUSB_REQ_TYPE_VENDOR, - .direction = direction + .direction = direction & 0x01u }, .bRequest = request, .wValue = tu_htole16 ( value ), @@ -1265,6 +1265,11 @@ static int32_t ch341_read_reg_request ( cdch_interface_t* p_cdc, uint16_t reg, u */ // calculate baudrate devisors // Parts of this functions have been taken over from Linux driver /drivers/usb/serial/ch341.c + +static inline uint32_t clamp_val(uint32_t val, uint32_t minval, uint32_t maxval) { + return tu_min32(tu_max32(val, minval), maxval); +} + static int32_t ch341_get_divisor ( cdch_interface_t* p_cdc, uint32_t speed ) { uint32_t fact, div, clk_div; bool force_fact0 = false; @@ -1280,9 +1285,6 @@ static int32_t ch341_get_divisor ( cdch_interface_t* p_cdc, uint32_t speed ) { * Clamp to supported range, this makes the (ps < 0) and (div < 2) * sanity checks below redundant. */ - inline uint32_t max ( uint32_t val, uint32_t maxval ) { return val > maxval ? val : maxval; } - inline uint32_t min ( uint32_t val, uint32_t minval ) { return val < minval ? val : minval; } - inline uint32_t clamp_val ( uint32_t val, uint32_t minval, uint32_t maxval ) { return min ( max ( val, minval ), maxval ); } speed = clamp_val(speed, CH341_MIN_BPS, CH341_MAX_BPS); /* @@ -1297,7 +1299,7 @@ static int32_t ch341_get_divisor ( cdch_interface_t* p_cdc, uint32_t speed ) { if (ps < 0) return -EINVAL; /* Determine corresponding divisor, rounding down. */ - clk_div = CH341_CLK_DIV(ps, fact); + clk_div = CH341_CLK_DIV((uint32_t) ps, fact); div = CH341_CLKRATE / (clk_div * speed); /* Some devices require a lower base clock if ps < 3. */ @@ -1333,19 +1335,20 @@ static int32_t ch341_get_divisor ( cdch_interface_t* p_cdc, uint32_t speed ) { fact = 0; } - return (0x100 - div) << 8 | fact << 2 | ps; + return (int32_t) ((0x100 - div) << 8 | fact << 2 | (uint32_t) ps); } // set baudrate (low level) // do not confuse with ch34x_set_baudrate // Parts of this functions have been taken over from Linux driver /drivers/usb/serial/ch341.c -static int32_t ch341_set_baudrate ( cdch_interface_t* p_cdc, uint32_t baud_rate, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) { - int val; - +static int32_t ch341_set_baudrate (cdch_interface_t* p_cdc, uint32_t baud_rate, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) { if (!baud_rate) return -EINVAL; - val = ch341_get_divisor(p_cdc, baud_rate); - if (val < 0) return -EINVAL; + int ret; + ret = ch341_get_divisor(p_cdc, baud_rate); + if (ret < 0) return -EINVAL; + + uint16_t val = (uint16_t) ret; /* * CH341A buffers data until a full endpoint-size packet (32 bytes) @@ -1355,7 +1358,7 @@ static int32_t ch341_set_baudrate ( cdch_interface_t* p_cdc, uint32_t baud_rate, * inverted. */ if ( p_cdc->ch34x.version > 0x27 ) { - val |= BIT(7); + val = (val | BIT(7)); } return ch341_write_reg ( p_cdc, CH341_REG_DIVISOR << 8 | CH341_REG_PRESCALER, val, complete_cb, user_data ); @@ -1449,8 +1452,13 @@ static bool ch34x_set_baudrate ( cdch_interface_t* p_cdc, uint32_t baudrate, tuh return ch341_set_baudrate ( p_cdc, baud_le, complete_cb ? ch34x_control_complete : NULL, user_data ); } -static bool ch34x_set_modem_ctrl ( cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) { +static bool ch34x_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { TU_LOG_DRV("CDC CH34x Set Control Line State\r\n"); + (void) p_cdc; + (void) line_state; + (void) complete_cb; + (void) user_data; + // todo later return false; } From 1f2901e8b12258c953e3c338897f188c98b5eaed Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 15 Jan 2024 18:42:39 +0700 Subject: [PATCH 048/454] fix conflict of BIT() macro --- src/class/cdc/cdc_host.c | 2 +- src/class/cdc/serial/ch34x.h | 11 ++++------- src/common/tusb_common.h | 1 + 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 0cc35da52..ca5bfff04 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -1358,7 +1358,7 @@ static int32_t ch341_set_baudrate (cdch_interface_t* p_cdc, uint32_t baud_rate, * inverted. */ if ( p_cdc->ch34x.version > 0x27 ) { - val = (val | BIT(7)); + val = (val | TU_BIT(7)); } return ch341_write_reg ( p_cdc, CH341_REG_DIVISOR << 8 | CH341_REG_PRESCALER, val, complete_cb, user_data ); diff --git a/src/class/cdc/serial/ch34x.h b/src/class/cdc/serial/ch34x.h index 94e18b252..4a5e61bbd 100644 --- a/src/class/cdc/serial/ch34x.h +++ b/src/class/cdc/serial/ch34x.h @@ -29,7 +29,7 @@ #include -#define BIT(nr) ( (uint32_t)1 << (nr) ) +//#define BIT(nr) ( (uint32_t)1 << (nr) ) #define CH34X_BUFFER_SIZE 2 @@ -93,20 +93,17 @@ #define CH341_LCR_CS6 0x01 #define CH341_LCR_CS5 0x00 -#define CH341_QUIRK_LIMITED_PRESCALER BIT(0) -#define CH341_QUIRK_SIMULATE_BREAK BIT(1) +#define CH341_QUIRK_LIMITED_PRESCALER TU_BIT(0) +#define CH341_QUIRK_SIMULATE_BREAK TU_BIT(1) #define CH341_CLKRATE 48000000 #define CH341_CLK_DIV(ps, fact) (1 << (12 - 3 * (ps) - (fact))) #define CH341_MIN_RATE(ps) (CH341_CLKRATE / (CH341_CLK_DIV((ps), 1) * 512)) /* Supported range is 46 to 3000000 bps. */ -#define CH341_MIN_BPS DIV_ROUND_UP(CH341_CLKRATE, CH341_CLK_DIV(0, 0) * 256) +#define CH341_MIN_BPS TU_DIV_CEIL(CH341_CLKRATE, CH341_CLK_DIV(0, 0) * 256) #define CH341_MAX_BPS (CH341_CLKRATE / (CH341_CLK_DIV(3, 0) * 2)) -#define DIV_ROUND_UP __KERNEL_DIV_ROUND_UP -#define __KERNEL_DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) - // error codes #define EINVAL 22 /* Invalid argument */ diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index caeb5f2ef..1f08ce4ed 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -37,6 +37,7 @@ #define TU_ARRAY_SIZE(_arr) ( sizeof(_arr) / sizeof(_arr[0]) ) #define TU_MIN(_x, _y) ( ( (_x) < (_y) ) ? (_x) : (_y) ) #define TU_MAX(_x, _y) ( ( (_x) > (_y) ) ? (_x) : (_y) ) +#define TU_DIV_CEIL(n, d) (((n) + (d) - 1) / (d)) #define TU_U16(_high, _low) ((uint16_t) (((_high) << 8) | (_low))) #define TU_U16_HIGH(_u16) ((uint8_t) (((_u16) >> 8) & 0x00ff)) From aa58cdcfa6a35cf5d903eaffd304db4834ce56ec Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 16 Jan 2024 01:28:29 +0700 Subject: [PATCH 049/454] change CFG_TUH_CDC_FTDI/CP210X_PID_LIST to CFG_TUH_CDC_FTDI/CP210X_VID_PID_LIST which contains both vid and pid. --- .idea/cmake.xml | 2 +- src/class/cdc/cdc_host.c | 24 ++++++++++-------------- src/tusb_option.h | 18 ++++++++++-------- 3 files changed, 21 insertions(+), 23 deletions(-) diff --git a/.idea/cmake.xml b/.idea/cmake.xml index 432e44172..3cb883e62 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -80,7 +80,7 @@ - + \ No newline at end of file diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 79477ef53..2463671c6 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -91,9 +91,9 @@ static bool acm_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfe #if CFG_TUH_CDC_FTDI #include "serial/ftdi_sio.h" -static uint16_t const ftdi_pids[] = { CFG_TUH_CDC_FTDI_PID_LIST }; +static uint16_t const ftdi_vid_pid_list[][2] = {CFG_TUH_CDC_FTDI_VID_PID_LIST }; enum { - FTDI_PID_COUNT = sizeof(ftdi_pids) / sizeof(ftdi_pids[0]) + FTDI_PID_COUNT = sizeof(ftdi_vid_pid_list) / sizeof(ftdi_vid_pid_list[0]) }; // Store last request baudrate since divisor to baudrate is not easy @@ -110,9 +110,9 @@ static bool ftdi_sio_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tu #if CFG_TUH_CDC_CP210X #include "serial/cp210x.h" -static uint16_t const cp210x_pids[] = { CFG_TUH_CDC_CP210X_PID_LIST }; +static uint16_t const cp210x_vid_pid_list[][2] = {CFG_TUH_CDC_CP210X_VID_PID_LIST }; enum { - CP210X_PID_COUNT = sizeof(cp210x_pids) / sizeof(cp210x_pids[0]) + CP210X_PID_COUNT = sizeof(cp210x_vid_pid_list) / sizeof(cp210x_vid_pid_list[0]) }; static bool cp210x_open(uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len); @@ -647,21 +647,17 @@ bool cdch_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const *itf_d TU_VERIFY(tuh_vid_pid_get(daddr, &vid, &pid)); #if CFG_TUH_CDC_FTDI - if (TU_FTDI_VID == vid) { - for (size_t i = 0; i < FTDI_PID_COUNT; i++) { - if (ftdi_pids[i] == pid) { - return ftdi_open(daddr, itf_desc, max_len); - } + for (size_t i = 0; i < FTDI_PID_COUNT; i++) { + if (ftdi_vid_pid_list[i][0] == vid && ftdi_vid_pid_list[i][1] == pid) { + return ftdi_open(daddr, itf_desc, max_len); } } #endif #if CFG_TUH_CDC_CP210X - if (TU_CP210X_VID == vid) { - for (size_t i = 0; i < CP210X_PID_COUNT; i++) { - if (cp210x_pids[i] == pid) { - return cp210x_open(daddr, itf_desc, max_len); - } + for (size_t i = 0; i < CP210X_PID_COUNT; i++) { + if (cp210x_vid_pid_list[i][0] == vid && cp210x_vid_pid_list[i][1] == pid) { + return cp210x_open(daddr, itf_desc, max_len); } } #endif diff --git a/src/tusb_option.h b/src/tusb_option.h index a76281c0c..57f026312 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -453,10 +453,12 @@ #define CFG_TUH_CDC_FTDI 0 #endif -#ifndef CFG_TUH_CDC_FTDI_PID_LIST - // List of product IDs that can use the FTDI CDC driver - #define CFG_TUH_CDC_FTDI_PID_LIST \ - 0x6001, 0x6006, 0x6010, 0x6011, 0x6014, 0x6015, 0x8372, 0xFBFA, 0xCD18 +#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 #ifndef CFG_TUH_CDC_CP210X @@ -464,10 +466,10 @@ #define CFG_TUH_CDC_CP210X 0 #endif -#ifndef CFG_TUH_CDC_CP210X_PID_LIST - // List of product IDs that can use the CP210X CDC driver - #define CFG_TUH_CDC_CP210X_PID_LIST \ - 0xEA60, 0xEA70 +#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 #ifndef CFG_TUH_HID From e2aa671346103d3ed80c2849350488d5ddf2e0dc Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 16 Jan 2024 12:54:39 +0700 Subject: [PATCH 050/454] move open() ad vid_pid_list into serial driver struct --- src/class/cdc/cdc_host.c | 102 ++++++++++++++++++--------------------- 1 file changed, 47 insertions(+), 55 deletions(-) diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index c018cf057..91e35ec8c 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -104,10 +104,7 @@ static bool acm_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfe #if CFG_TUH_CDC_FTDI #include "serial/ftdi_sio.h" -static uint16_t const ftdi_vid_pid_list[][2] = {CFG_TUH_CDC_FTDI_VID_PID_LIST }; -enum { - FTDI_PID_COUNT = TU_ARRAY_SIZE(ftdi_vid_pid_list) -}; +static uint16_t const ftdi_vid_pid_list[][2] = {CFG_TUH_CDC_FTDI_VID_PID_LIST}; // Store last request baudrate since divisor to baudrate is not easy static uint32_t _ftdi_requested_baud; @@ -122,10 +119,7 @@ static bool ftdi_sio_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tu #if CFG_TUH_CDC_CP210X #include "serial/cp210x.h" -static uint16_t const cp210x_vid_pid_list[][2] = {CFG_TUH_CDC_CP210X_VID_PID_LIST }; -enum { - CP210X_PID_COUNT = TU_ARRAY_SIZE(cp210x_vid_pid_list) -}; +static uint16_t const cp210x_vid_pid_list[][2] = {CFG_TUH_CDC_CP210X_VID_PID_LIST}; static bool cp210x_open(uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len); static void cp210x_process_config(tuh_xfer_t* xfer); @@ -137,10 +131,7 @@ static bool cp210x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_ #if CFG_TUH_CDC_CH34X #include "serial/ch34x.h" -static uint16_t const ch34x_vids_pids[][2] = { CFG_TUH_CDC_CH34X_VID_PID_LIST }; -enum { - CH34X_VID_PID_COUNT = TU_ARRAY_SIZE(ch34x_vids_pids) -}; +static uint16_t const ch34x_vid_pid_list[][2] = {CFG_TUH_CDC_CH34X_VID_PID_LIST}; static bool ch34x_open ( uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len ); static void ch34x_process_config ( tuh_xfer_t* xfer ); @@ -164,9 +155,14 @@ enum { #if CFG_TUH_CDC_CH34X SERIAL_DRIVER_CH34X, #endif + + SERIAL_DRIVER_COUNT }; typedef struct { + uint16_t const (*vid_pid_list)[2]; + uint16_t const vid_pid_count; + bool (*const open)(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len); void (*const process_set_config)(tuh_xfer_t* xfer); bool (*const set_control_line_state)(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data); bool (*const set_baudrate)(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data); @@ -174,36 +170,50 @@ typedef struct { // Note driver list must be in the same order as SERIAL_DRIVER enum static const cdch_serial_driver_t serial_drivers[] = { - { .process_set_config = acm_process_config, - .set_control_line_state = acm_set_control_line_state, - .set_baudrate = acm_set_baudrate + { + .vid_pid_list = NULL, + .vid_pid_count = 0, + .open = acm_open, + .process_set_config = acm_process_config, + .set_control_line_state = acm_set_control_line_state, + .set_baudrate = acm_set_baudrate }, #if CFG_TUH_CDC_FTDI - { .process_set_config = ftdi_process_config, - .set_control_line_state = ftdi_sio_set_modem_ctrl, - .set_baudrate = ftdi_sio_set_baudrate + { + .vid_pid_list = ftdi_vid_pid_list, + .vid_pid_count = TU_ARRAY_SIZE(ftdi_vid_pid_list), + .open = ftdi_open, + .process_set_config = ftdi_process_config, + .set_control_line_state = ftdi_sio_set_modem_ctrl, + .set_baudrate = ftdi_sio_set_baudrate }, #endif #if CFG_TUH_CDC_CP210X - { .process_set_config = cp210x_process_config, - .set_control_line_state = cp210x_set_modem_ctrl, - .set_baudrate = cp210x_set_baudrate + { + .vid_pid_list = cp210x_vid_pid_list, + .vid_pid_count = TU_ARRAY_SIZE(cp210x_vid_pid_list), + .open = cp210x_open, + .process_set_config = cp210x_process_config, + .set_control_line_state = cp210x_set_modem_ctrl, + .set_baudrate = cp210x_set_baudrate }, #endif #if CFG_TUH_CDC_CH34X - { .process_set_config = ch34x_process_config, - .set_control_line_state = ch34x_set_modem_ctrl, - .set_baudrate = ch34x_set_baudrate + { + .vid_pid_list = ch34x_vid_pid_list, + .vid_pid_count = TU_ARRAY_SIZE(ch34x_vid_pid_list), + .open = ch34x_open, + .process_set_config = ch34x_process_config, + .set_control_line_state = ch34x_set_modem_ctrl, + .set_baudrate = ch34x_set_baudrate }, -#endif + #endif }; -enum { - SERIAL_DRIVER_COUNT = TU_ARRAY_SIZE(serial_drivers) -}; +TU_VERIFY_STATIC(TU_ARRAY_SIZE(serial_drivers) == SERIAL_DRIVER_COUNT, "Serial driver count mismatch"); //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION @@ -639,36 +649,20 @@ bool cdch_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const *itf_d CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass) { return acm_open(daddr, itf_desc, max_len); } - #if CFG_TUH_CDC_FTDI || CFG_TUH_CDC_CP210X || CFG_TUH_CDC_CH34X - else if (TUSB_CLASS_VENDOR_SPECIFIC == itf_desc->bInterfaceClass) { + else if (SERIAL_DRIVER_COUNT > 1 && + TUSB_CLASS_VENDOR_SPECIFIC == itf_desc->bInterfaceClass) { uint16_t vid, pid; TU_VERIFY(tuh_vid_pid_get(daddr, &vid, &pid)); - #if CFG_TUH_CDC_FTDI - for (size_t i = 0; i < FTDI_PID_COUNT; i++) { - if (ftdi_vid_pid_list[i][0] == vid && ftdi_vid_pid_list[i][1] == pid) { - return ftdi_open(daddr, itf_desc, max_len); + for (size_t dr = 1; dr < SERIAL_DRIVER_COUNT; dr++) { + cdch_serial_driver_t const* driver = &serial_drivers[dr]; + for (size_t i = 0; i < driver->vid_pid_count; i++) { + if (driver->vid_pid_list[i][0] == vid && driver->vid_pid_list[i][1] == pid) { + return driver->open(daddr, itf_desc, max_len); + } } } - #endif - - #if CFG_TUH_CDC_CP210X - for (size_t i = 0; i < CP210X_PID_COUNT; i++) { - if (cp210x_vid_pid_list[i][0] == vid && cp210x_vid_pid_list[i][1] == pid) { - return cp210x_open(daddr, itf_desc, max_len); - } - } - #endif - - #if CFG_TUH_CDC_CH34X - for (size_t i = 0; i < CH34X_VID_PID_COUNT; i++) { - if ( ch34x_vids_pids[i][0] == vid && ch34x_vids_pids[i][1] == pid ) { - return ch34x_open(daddr, itf_desc, max_len); - } - } - #endif } - #endif return false; } @@ -683,9 +677,7 @@ static void set_config_complete(cdch_interface_t * p_cdc, uint8_t idx, uint8_t i usbh_driver_set_config_complete(p_cdc->daddr, itf_num); } - -bool cdch_set_config(uint8_t daddr, uint8_t itf_num) -{ +bool cdch_set_config(uint8_t daddr, uint8_t itf_num) { tusb_control_request_t request; request.wIndex = tu_htole16((uint16_t) itf_num); From 4e6408ea4940085f66c676772d77e3951e82ea11 Mon Sep 17 00:00:00 2001 From: IngHK Date: Tue, 16 Jan 2024 08:07:22 +0100 Subject: [PATCH 051/454] CDCh host: further work on CH340/CH341 support --- examples/host/cdc_msc_hid/src/tusb_config.h | 3 +- .../cdc_msc_hid_freertos/src/tusb_config.h | 3 +- src/class/cdc/cdc_debug.h | 65 ++ src/class/cdc/cdc_device.c | 21 +- src/class/cdc/cdc_host.c | 570 ++++++++---------- src/class/cdc/cdc_host.h | 4 +- src/class/cdc/serial/ch34x.h | 103 +--- 7 files changed, 370 insertions(+), 399 deletions(-) create mode 100644 src/class/cdc/cdc_debug.h diff --git a/examples/host/cdc_msc_hid/src/tusb_config.h b/examples/host/cdc_msc_hid/src/tusb_config.h index 76d59c316..ac14ef97e 100644 --- a/examples/host/cdc_msc_hid/src/tusb_config.h +++ b/examples/host/cdc_msc_hid/src/tusb_config.h @@ -120,8 +120,7 @@ //------------- CDC -------------// // Set Line Control state on enumeration/mounted: -// DTR ( bit 0), RTS (bit 1) -#define CFG_TUH_CDC_LINE_CONTROL_ON_ENUM 0x03 +#define CFG_TUH_CDC_LINE_CONTROL_ON_ENUM ( CDC_CONTROL_LINE_STATE_RTS | CDC_CONTROL_LINE_STATE_DTR ) // Set Line Coding on enumeration/mounted, value for cdc_line_coding_t // bit rate = 115200, 1 stop bit, no parity, 8 bit data width 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 bb7c3388d..1b68dd2d8 100644 --- a/examples/host/cdc_msc_hid_freertos/src/tusb_config.h +++ b/examples/host/cdc_msc_hid_freertos/src/tusb_config.h @@ -125,8 +125,7 @@ //------------- CDC -------------// // Set Line Control state on enumeration/mounted: -// DTR ( bit 0), RTS (bit 1) -#define CFG_TUH_CDC_LINE_CONTROL_ON_ENUM 0x03 +#define CFG_TUH_CDC_LINE_CONTROL_ON_ENUM ( CDC_CONTROL_LINE_STATE_RTS | CDC_CONTROL_LINE_STATE_DTR ) // Set Line Coding on enumeration/mounted, value for cdc_line_coding_t // bit rate = 115200, 1 stop bit, no parity, 8 bit data width diff --git a/src/class/cdc/cdc_debug.h b/src/class/cdc/cdc_debug.h new file mode 100644 index 000000000..879e49a50 --- /dev/null +++ b/src/class/cdc/cdc_debug.h @@ -0,0 +1,65 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2023 Ha Thach (tinyusb.org) + * Copyright (c) 2023 IngHK Heiko Kuester + * + * 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_CDC_DEBUG_H_ +#define _TUSB_CDC_DEBUG_H_ + +#include "cdc.h" + +#ifdef __cplusplus + extern "C" { +#endif + +// logging of line coding +#define TU_LOG_LINE_CODING(PRE_TEXT,LINE_CODING) \ + TU_LOG_DRV(PRE_TEXT "Line Coding %lu Bd, %u%c%s\r\n", \ + LINE_CODING.bit_rate, \ + LINE_CODING.data_bits, \ + LINE_CODING.parity == CDC_LINE_CODING_PARITY_NONE ? 'N' : \ + LINE_CODING.parity == CDC_LINE_CODING_PARITY_ODD ? 'O' : \ + LINE_CODING.parity == CDC_LINE_CODING_PARITY_EVEN ? 'E' : \ + LINE_CODING.parity == CDC_LINE_CODING_PARITY_MARK ? 'M' : \ + LINE_CODING.parity == CDC_LINE_CODING_PARITY_SPACE ? 'S' : '?', \ + LINE_CODING.stop_bits == CDC_LINE_CODING_STOP_BITS_1 ? "1" : \ + LINE_CODING.stop_bits == CDC_LINE_CODING_STOP_BITS_1_5 ? "1.5" : \ + LINE_CODING.stop_bits == CDC_LINE_CODING_STOP_BITS_2 ? "2" : "?") + +// logging of baudrate +#define TU_LOG_BAUDRATE(PRE_TEXT,BAUDRATE) \ + TU_LOG_DRV(PRE_TEXT "Baudrate %lu Bd\r\n", BAUDRATE) + + // logging of control line state +#define TU_LOG_CONTROL_LINE_STATE(PRE_TEXT,LINE_STATE) \ + TU_LOG_DRV(PRE_TEXT "Control Line State RTS%c DTR%c\r\n", \ + LINE_STATE & CDC_CONTROL_LINE_STATE_RTS ? '+' : '-', \ + LINE_STATE & CDC_CONTROL_LINE_STATE_DTR ? '+' : '-' ) + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_CDC_DEBUG_H_ */ diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index c26264e60..b763419e7 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -32,6 +32,9 @@ #include "device/usbd_pvt.h" #include "cdc_device.h" +#if 0 // TODO activate and test +#include "cdc_debug.h" +#endif // Level where CFG_TUSB_DEBUG must be at least for this driver is logged #ifndef CFG_TUD_CDC_LOG_LEVEL @@ -360,7 +363,11 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t case CDC_REQUEST_SET_LINE_CODING: if (stage == CONTROL_STAGE_SETUP) { - TU_LOG_DRV(" Set Line Coding\r\n"); + #if 0 // TODO activate, test and remove else + TU_LOG_LINE_CODING(" Set ", p_cdc->line_coding); + #else + TU_LOG_DRV(" Set Line Coding\r\n"); + #endif tud_control_xfer(rhport, request, &p_cdc->line_coding, sizeof(cdc_line_coding_t)); } else if ( stage == CONTROL_STAGE_ACK) @@ -372,7 +379,11 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t case CDC_REQUEST_GET_LINE_CODING: if (stage == CONTROL_STAGE_SETUP) { - TU_LOG_DRV(" Get Line Coding\r\n"); + #if 0 // TODO activate, test and remove else + TU_LOG_LINE_CODING(" Get ", p_cdc->line_coding); + #else + TU_LOG_DRV(" Get Line Coding\r\n"); + #endif tud_control_xfer(rhport, request, &p_cdc->line_coding, sizeof(cdc_line_coding_t)); } break; @@ -397,7 +408,11 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t // Disable fifo overwriting if DTR bit is set tu_fifo_set_overwritable(&p_cdc->tx_ff, !dtr); - TU_LOG_DRV(" Set Control Line State: DTR = %d, RTS = %d\r\n", dtr, rts); + #if 0 // TODO activate, test and remove else + TU_LOG_CONTROL_LINE_STATE(" Set ", p_cdc->line_state); + #else + TU_LOG_DRV(" Set Control Line State: DTR = %d, RTS = %d\r\n", dtr, rts); + #endif // Invoke callback if ( tud_cdc_line_state_cb ) tud_cdc_line_state_cb(itf, dtr, rts); diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index f6a6773e0..d46bfecb4 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -2,7 +2,7 @@ * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) - * Copyright (c) 2023 Heiko Kuester (CH34x support) + * Copyright (c) 2023 IngHK Heiko Kuester * * 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,6 +33,7 @@ #include "host/usbh_pvt.h" #include "cdc_host.h" +#include "cdc_debug.h" // Level where CFG_TUSB_DEBUG must be at least for this driver is logged #ifndef CFG_TUH_CDC_LOG_LEVEL @@ -55,7 +56,7 @@ typedef struct { cdc_acm_capability_t acm_capability; uint8_t ep_notif; - uint8_t line_state; // DTR (bit0), RTS (bit1) + uint8_t line_state; // RTS, DTR (refer enums CDC_CONTROL_LINE_STATE_RTS, CDC_CONTROL_LINE_STATE_DTR) TU_ATTR_ALIGNED(4) cdc_line_coding_t line_coding; // Baudrate, stop bits, parity, data width tuh_xfer_cb_t user_control_cb; @@ -70,16 +71,9 @@ typedef struct { uint8_t rx_ff_buf[CFG_TUH_CDC_TX_BUFSIZE]; CFG_TUH_MEM_ALIGN uint8_t rx_ep_buf[CFG_TUH_CDC_TX_EPSIZE]; } stream; - #if CFG_TUH_CDC_CH34X - struct { - uint32_t baud_rate; - uint8_t mcr; - uint8_t msr; - uint8_t lcr; - uint32_t quirks; - uint8_t version; - } ch34x; - #endif +#if CFG_TUH_CDC_FTDI || CFG_TUH_CDC_CH34X + uint32_t baudrate_requested; +#endif } cdch_interface_t; CFG_TUH_MEM_SECTION @@ -106,12 +100,10 @@ enum { FTDI_PID_COUNT = sizeof(ftdi_pids) / sizeof(ftdi_pids[0]) }; -// Store last request baudrate since divisor to baudrate is not easy -static uint32_t _ftdi_requested_baud; - static bool ftdi_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len); static void ftdi_process_config(tuh_xfer_t* xfer); +static bool ftdi_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data); static bool ftdi_sio_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data); static bool ftdi_sio_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data); #endif @@ -128,6 +120,7 @@ enum { static bool cp210x_open(uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len); static void cp210x_process_config(tuh_xfer_t* xfer); +static bool cp210x_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data); static bool cp210x_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data); static bool cp210x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data); #endif @@ -144,6 +137,7 @@ enum { static bool ch34x_open ( uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len ); static void ch34x_process_config ( tuh_xfer_t* xfer ); +static bool ch34x_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data); static bool ch34x_set_modem_ctrl ( cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data ); static bool ch34x_set_baudrate ( cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data ); #endif @@ -169,35 +163,40 @@ typedef struct { void (*const process_set_config)(tuh_xfer_t* xfer); bool (*const set_control_line_state)(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data); bool (*const set_baudrate)(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data); + bool (*const set_line_coding)(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data); } cdch_serial_driver_t; // Note driver list must be in the same order as SERIAL_DRIVER enum static const cdch_serial_driver_t serial_drivers[] = { { .process_set_config = acm_process_config, .set_control_line_state = acm_set_control_line_state, - .set_baudrate = acm_set_baudrate + .set_baudrate = acm_set_baudrate, + .set_line_coding = acm_set_line_coding }, #if CFG_TUH_CDC_FTDI { .process_set_config = ftdi_process_config, .set_control_line_state = ftdi_sio_set_modem_ctrl, - .set_baudrate = ftdi_sio_set_baudrate + .set_baudrate = ftdi_sio_set_baudrate, + .set_line_coding = ftdi_set_line_coding }, #endif #if CFG_TUH_CDC_CP210X { .process_set_config = cp210x_process_config, .set_control_line_state = cp210x_set_modem_ctrl, - .set_baudrate = cp210x_set_baudrate + .set_baudrate = cp210x_set_baudrate, + .set_line_coding = cp210x_set_line_coding }, #endif #if CFG_TUH_CDC_CH34X { .process_set_config = ch34x_process_config, .set_control_line_state = ch34x_set_modem_ctrl, - .set_baudrate = ch34x_set_baudrate + .set_baudrate = ch34x_set_baudrate, + .set_line_coding = ch34x_set_line_coding }, -#endif + #endif }; enum { @@ -304,6 +303,7 @@ bool tuh_cdc_get_dtr(uint8_t idx) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); + TU_LOG_CONTROL_LINE_STATE("CDCh Local ", p_cdc->line_state); return (p_cdc->line_state & CDC_CONTROL_LINE_STATE_DTR) ? true : false; } @@ -312,6 +312,7 @@ bool tuh_cdc_get_rts(uint8_t idx) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); + TU_LOG_CONTROL_LINE_STATE("CDCh Local ", p_cdc->line_state); return (p_cdc->line_state & CDC_CONTROL_LINE_STATE_RTS) ? true : false; } @@ -322,6 +323,7 @@ bool tuh_cdc_get_local_line_coding(uint8_t idx, cdc_line_coding_t* line_coding) TU_VERIFY(p_cdc); *line_coding = p_cdc->line_coding; + TU_LOG_LINE_CODING("CDCh Get ", p_cdc->line_coding); return true; } @@ -440,7 +442,7 @@ static void cdch_internal_control_complete(tuh_xfer_t* xfer) case FTDI_SIO_SET_BAUD_RATE: // convert from divisor to baudrate is not supported - p_cdc->line_coding.bit_rate = _ftdi_requested_baud; + p_cdc->line_coding.bit_rate = p_cdc->baudrate_requested; break; default: break; @@ -465,12 +467,6 @@ static void cdch_internal_control_complete(tuh_xfer_t* xfer) break; #endif - #if CFG_TUH_CDC_CH34X - case SERIAL_DRIVER_CH34X: - TU_ASSERT(false, ); // see special ch34x_control_complete function - break; - #endif - default: break; } } @@ -487,7 +483,7 @@ bool tuh_cdc_set_control_line_state(uint8_t idx, uint16_t line_state, tuh_xfer_c cdch_serial_driver_t const* driver = &serial_drivers[p_cdc->serial_drid]; if ( complete_cb ) { - return driver->set_control_line_state(p_cdc, line_state, complete_cb, user_data); + TU_VERIFY(driver->set_control_line_state(p_cdc, line_state, complete_cb, user_data)); }else { // blocking xfer_result_t result = XFER_RESULT_INVALID; @@ -501,8 +497,10 @@ bool tuh_cdc_set_control_line_state(uint8_t idx, uint16_t line_state, tuh_xfer_c TU_VERIFY(ret && result == XFER_RESULT_SUCCESS); p_cdc->line_state = (uint8_t) line_state; - return true; } + TU_LOG_CONTROL_LINE_STATE("CDCh Set ", p_cdc->line_state); + + return true; } bool tuh_cdc_set_baudrate(uint8_t idx, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { @@ -511,7 +509,7 @@ bool tuh_cdc_set_baudrate(uint8_t idx, uint32_t baudrate, tuh_xfer_cb_t complete cdch_serial_driver_t const* driver = &serial_drivers[p_cdc->serial_drid]; if ( complete_cb ) { - return driver->set_baudrate(p_cdc, baudrate, complete_cb, user_data); + TU_VERIFY(driver->set_baudrate(p_cdc, baudrate, complete_cb, user_data)); }else { // blocking xfer_result_t result = XFER_RESULT_INVALID; @@ -525,23 +523,24 @@ bool tuh_cdc_set_baudrate(uint8_t idx, uint32_t baudrate, tuh_xfer_cb_t complete TU_VERIFY(ret && result == XFER_RESULT_SUCCESS); p_cdc->line_coding.bit_rate = baudrate; - return true; } + TU_LOG_BAUDRATE("CDCh Set ", p_cdc->line_coding.bit_rate); + + return true; } bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { cdch_interface_t* p_cdc = get_itf(idx); - // only ACM support this set line coding request - TU_VERIFY(p_cdc && p_cdc->serial_drid == SERIAL_DRIVER_ACM); - TU_VERIFY(p_cdc->acm_capability.support_line_request); + TU_VERIFY(p_cdc && p_cdc->serial_drid < SERIAL_DRIVER_COUNT); + cdch_serial_driver_t const* driver = &serial_drivers[p_cdc->serial_drid]; if ( complete_cb ) { - return acm_set_line_coding(p_cdc, line_coding, complete_cb, user_data); - }else { + TU_VERIFY(driver->set_line_coding(p_cdc, line_coding, complete_cb, user_data)); + } else { // blocking xfer_result_t result = XFER_RESULT_INVALID; - bool ret = acm_set_line_coding(p_cdc, line_coding, complete_cb, (uintptr_t) &result); + bool ret = driver->set_line_coding(p_cdc, line_coding, complete_cb, (uintptr_t) &result); if (user_data) { // user_data is not NULL, return result via user_data @@ -551,8 +550,10 @@ bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding, TU_VERIFY(ret && result == XFER_RESULT_SUCCESS); p_cdc->line_coding = *line_coding; - return true; } + TU_LOG_LINE_CODING("CDCh Set ", p_cdc->line_coding); + + return true; } //--------------------------------------------------------------------+ @@ -684,13 +685,8 @@ bool cdch_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const *itf_d { return acm_open(daddr, itf_desc, max_len); } -<<<<<<< HEAD #if CFG_TUH_CDC_FTDI || CFG_TUH_CDC_CP210X || CFG_TUH_CDC_CH34X - else if ( 0xff == itf_desc->bInterfaceClass ) -======= - #if CFG_TUH_CDC_FTDI || CFG_TUH_CDC_CP210X else if ( TUSB_CLASS_VENDOR_SPECIFIC == itf_desc->bInterfaceClass ) ->>>>>>> remotes/hathach/master { uint16_t vid, pid; TU_VERIFY(tuh_vid_pid_get(daddr, &vid, &pid)); @@ -816,6 +812,8 @@ static bool acm_open(uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint1 TU_ASSERT(open_ep_stream_pair(p_cdc, (tusb_desc_endpoint_t const *) p_desc)); } + TU_LOG_DRV("[%u] CDCh ACM opened\r\n", daddr); + return true; } @@ -852,6 +850,12 @@ static void acm_process_config(tuh_xfer_t* xfer) TU_ATTR_FALLTHROUGH; case CONFIG_ACM_COMPLETE: + #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM + TU_LOG_LINE_CODING("CDCh ACM Init ", p_cdc->line_coding); + #endif + #if CFG_TUH_CDC_LINE_CONTROL_ON_ENUM + TU_LOG_CONTROL_LINE_STATE("CDCh ACM Init", p_cdc->line_state); + #endif // itf_num+1 to account for data interface as well set_config_complete(p_cdc, idx, itf_num+1); break; @@ -893,6 +897,7 @@ static bool acm_set_control_line_state(cdch_interface_t* p_cdc, uint16_t line_st static bool acm_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { TU_LOG_DRV("CDC ACM Set Line Conding\r\n"); + TU_VERIFY(p_cdc->acm_capability.support_line_request); tusb_control_request_t const request = { .bmRequestType_bit = { @@ -994,6 +999,12 @@ static bool ftdi_sio_reset(cdch_interface_t* p_cdc, tuh_xfer_cb_t complete_cb, u return ftdi_sio_set_request(p_cdc, FTDI_SIO_RESET, FTDI_SIO_RESET_SIO, complete_cb, user_data); } +static bool ftdi_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data) +{ + TU_ASSERT(false, false); // TODO + return false; +} + static bool ftdi_sio_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { TU_LOG_DRV("CDC FTDI Set Control Line State\r\n"); @@ -1035,7 +1046,7 @@ static bool ftdi_sio_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tu TU_LOG_DRV("CDC FTDI Set BaudRate = %lu, divisor = 0x%04x\r\n", baudrate, divisor); p_cdc->user_control_cb = complete_cb; - _ftdi_requested_baud = baudrate; + p_cdc->baudrate_requested = baudrate; TU_ASSERT(ftdi_sio_set_request(p_cdc, FTDI_SIO_SET_BAUD_RATE, divisor, complete_cb ? cdch_internal_control_complete : NULL, user_data)); @@ -1088,6 +1099,14 @@ static void ftdi_process_config(tuh_xfer_t* xfer) { case CONFIG_FTDI_COMPLETE: set_config_complete(p_cdc, idx, itf_num); + #if 0 // TODO set data format + #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM + TU_LOG_LINE_CODING("CDCh FTDI Init ", p_cdc->line_coding); + #endif + #endif + #if CFG_TUH_CDC_LINE_CONTROL_ON_ENUM + TU_LOG_CONTROL_LINE_STATE("CDCh FTDI Init ", p_cdc->line_state); + #endif break; default: @@ -1166,6 +1185,12 @@ static bool cp210x_ifc_enable(cdch_interface_t* p_cdc, uint16_t enabled, tuh_xfe return cp210x_set_request(p_cdc, CP210X_IFC_ENABLE, enabled, NULL, 0, complete_cb, user_data); } +static bool cp210x_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data) +{ + TU_ASSERT(false, false); // TODO + return false; +} + static bool cp210x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { TU_LOG_DRV("CDC CP210x Set BaudRate = %lu\r\n", baudrate); uint32_t baud_le = tu_htole32(baudrate); @@ -1224,6 +1249,12 @@ static void cp210x_process_config(tuh_xfer_t* xfer) { case CONFIG_CP210X_COMPLETE: set_config_complete(p_cdc, idx, itf_num); + #if defined(CFG_TUH_CDC_LINE_CODING_ON_ENUM) && 0 // skip for now + TU_LOG_LINE_CODING("CDCh CP210x Init ", p_cdc->line_coding); + #endif + #if CFG_TUH_CDC_LINE_CONTROL_ON_ENUM + TU_LOG_CONTROL_LINE_STATE("CDCh CP210x Init ", p_cdc->line_state); + #endif break; default: break; @@ -1233,20 +1264,19 @@ static void cp210x_process_config(tuh_xfer_t* xfer) { #endif //--------------------------------------------------------------------+ -// CH34x +// CH34x (CH340 & CH341) //--------------------------------------------------------------------+ #if CFG_TUH_CDC_CH34X +#define CH34X_LOGS false + enum { - CONFIG_CH34X_STEP1 = 0, - CONFIG_CH34X_STEP2, - CONFIG_CH34X_STEP3, - CONFIG_CH34X_STEP4, - CONFIG_CH34X_STEP5, - CONFIG_CH34X_STEP6, - CONFIG_CH34X_STEP7, - CONFIG_CH34X_STEP8, + CONFIG_CH34X_READ_VERSION = 0, + CONFIG_CH34X_SERIAL_INIT, + CONFIG_CH34X_SPECIAL_REG_WRITE, + CONFIG_CH34X_FLOW_CONTROL, + CONFIG_CH34X_MODEM_CONTROL, CONFIG_CH34X_COMPLETE }; @@ -1259,17 +1289,22 @@ static bool ch34x_open ( uint8_t daddr, tusb_desc_interface_t const *itf_desc, u cdch_interface_t *p_cdc = make_new_itf ( daddr, itf_desc ); TU_VERIFY ( p_cdc ); - TU_LOG_DRV ( "CH34x opened\r\n" ); + p_cdc->serial_drid = SERIAL_DRIVER_CH34X; // endpoint pair tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const *) tu_desc_next ( itf_desc ); // data endpoints expected to be in pairs - return open_ep_stream_pair ( p_cdc, desc_ep ); + TU_ASSERT(open_ep_stream_pair(p_cdc, desc_ep), false); + + TU_LOG_DRV("[%u] CDCh CH34x opened\r\n", daddr); + + return true; } -static bool ch34x_set_request ( cdch_interface_t* p_cdc, uint8_t direction, uint8_t request, uint16_t value, uint16_t index, uint8_t* buffer, uint16_t length, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) +static bool ch34x_set_request ( cdch_interface_t* p_cdc, uint8_t direction, uint8_t request, uint16_t value, uint16_t index, + uint8_t* buffer, uint16_t length, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) { tusb_control_request_t const request_setup = { .bmRequestType_bit = { @@ -1297,212 +1332,66 @@ static bool ch34x_set_request ( cdch_interface_t* p_cdc, uint8_t direction, uint .setup = &request_setup, .buffer = enum_buf, .complete_cb = complete_cb, - // CH34x needs a special handling of bInterfaceNumber, because wIndex is used for other purposes and not for bInterfaceNumber - .user_data = (uintptr_t)( ( p_cdc->bInterfaceNumber & 0xff ) << 8 ) | ( user_data & 0xff ) + .user_data = user_data }; return tuh_control_xfer ( &xfer ); - return false; } -static bool ch341_control_out ( cdch_interface_t* p_cdc, uint8_t request, uint16_t value, uint16_t index, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) +static bool ch34x_control_out ( cdch_interface_t* p_cdc, uint8_t request, uint16_t value, uint16_t index, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) { return ch34x_set_request ( p_cdc, TUSB_DIR_OUT, request, value, index, /* buffer */ NULL, /* length */ 0, complete_cb, user_data ); } -static bool ch341_control_in ( cdch_interface_t* p_cdc, uint8_t request, uint16_t value, uint16_t index, uint8_t *buffer, uint16_t buffersize, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) +static bool ch34x_control_in ( cdch_interface_t* p_cdc, uint8_t request, uint16_t value, uint16_t index, + uint8_t *buffer, uint16_t buffersize, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) { return ch34x_set_request ( p_cdc, TUSB_DIR_IN, request, value, index, buffer, buffersize, complete_cb, user_data ); } -static int32_t ch341_write_reg ( cdch_interface_t* p_cdc, uint16_t reg, uint16_t value, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) +static bool ch34x_write_reg ( cdch_interface_t* p_cdc, uint16_t reg, uint16_t value, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) { - return ch341_control_out ( p_cdc, CH341_REQ_WRITE_REG, /* value */ reg, /* index */ value, complete_cb, user_data ); + return ch34x_control_out ( p_cdc, CH34X_REQ_WRITE_REG, /* value */ reg, /* index */ value, complete_cb, user_data ); } -static int32_t ch341_read_reg_request ( cdch_interface_t* p_cdc, uint16_t reg, uint8_t *buffer, uint16_t buffersize, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) +//static bool ch34x_read_reg_request ( cdch_interface_t* p_cdc, uint16_t reg, +// uint8_t *buffer, uint16_t buffersize, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) +//{ +// return ch34x_control_in ( p_cdc, CH34X_REQ_READ_REG, reg, /* index */ 0, buffer, buffersize, complete_cb, user_data ); +//} + +uint8_t ch34x_xfer_get_itf_num ( tuh_xfer_t* xfer ) +// CH34x needs a special handling to get bInterfaceNumber, because wIndex is used for other purposes and not for bInterfaceNumber +// CH340 and CH341 derivates have always only one interface, so it's OK to check only daddr { - return ch341_control_in ( p_cdc, CH341_REQ_READ_REG, reg, /* index */ 0, buffer, buffersize, complete_cb, user_data ); -} - -/* - * The device line speed is given by the following equation: - * - * baudrate = 48000000 / (2^(12 - 3 * ps - fact) * div), where - * - * 0 <= ps <= 3, - * 0 <= fact <= 1, - * 2 <= div <= 256 if fact = 0, or - * 9 <= div <= 256 if fact = 1 - */ -// calculate baudrate devisors -// Parts of this functions have been taken over from Linux driver /drivers/usb/serial/ch341.c -static int32_t ch341_get_divisor ( cdch_interface_t* p_cdc, uint32_t speed ) -{ - uint32_t fact, div, clk_div; - bool force_fact0 = false; - int32_t ps; - static const uint32_t ch341_min_rates[] = { - CH341_MIN_RATE(0), - CH341_MIN_RATE(1), - CH341_MIN_RATE(2), - CH341_MIN_RATE(3), - }; - - /* - * Clamp to supported range, this makes the (ps < 0) and (div < 2) - * sanity checks below redundant. - */ - inline uint32_t max ( uint32_t val, uint32_t maxval ) { return val > maxval ? val : maxval; } - inline uint32_t min ( uint32_t val, uint32_t minval ) { return val < minval ? val : minval; } - inline uint32_t clamp_val ( uint32_t val, uint32_t minval, uint32_t maxval ) { return min ( max ( val, minval ), maxval ); } - speed = clamp_val(speed, CH341_MIN_BPS, CH341_MAX_BPS); - - /* - * Start with highest possible base clock (fact = 1) that will give a - * divisor strictly less than 512. - */ - fact = 1; - for (ps = 3; ps >= 0; ps--) { - if (speed > ch341_min_rates[ps]) - break; - } - - if (ps < 0) - return -EINVAL; - - /* Determine corresponding divisor, rounding down. */ - clk_div = CH341_CLK_DIV(ps, fact); - div = CH341_CLKRATE / (clk_div * speed); - - /* Some devices require a lower base clock if ps < 3. */ - if (ps < 3 && (p_cdc->ch34x.quirks & CH341_QUIRK_LIMITED_PRESCALER)) - force_fact0 = true; - - /* Halve base clock (fact = 0) if required. */ - if (div < 9 || div > 255 || force_fact0) { - div /= 2; - clk_div *= 2; - fact = 0; - } - - if (div < 2) - return -EINVAL; - - /* - * Pick next divisor if resulting rate is closer to the requested one, - * scale up to avoid rounding errors on low rates. - */ - if (16 * CH341_CLKRATE / (clk_div * div) - 16 * speed >= - 16 * speed - 16 * CH341_CLKRATE / (clk_div * (div + 1))) - div++; - - /* - * Prefer lower base clock (fact = 0) if even divisor. - * - * Note that this makes the receiver more tolerant to errors. - */ - if (fact == 1 && div % 2 == 0) { - div /= 2; - fact = 0; - } - - return (0x100 - div) << 8 | fact << 2 | ps; -} - -// set baudrate (low level) -// do not confuse with ch34x_set_baudrate -// Parts of this functions have been taken over from Linux driver /drivers/usb/serial/ch341.c -static int32_t ch341_set_baudrate ( cdch_interface_t* p_cdc, uint32_t baud_rate, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) -{ - int val; - - if (!baud_rate) - return -EINVAL; - - val = ch341_get_divisor(p_cdc, baud_rate); - if (val < 0) - return -EINVAL; - - /* - * CH341A buffers data until a full endpoint-size packet (32 bytes) - * has been received unless bit 7 is set. - * - * At least one device with version 0x27 appears to have this bit - * inverted. - */ - if ( p_cdc->ch34x.version > 0x27 ) - val |= BIT(7); - - return ch341_write_reg ( p_cdc, CH341_REG_DIVISOR << 8 | CH341_REG_PRESCALER, val, complete_cb, user_data ); -} - -// set lcr register -// Parts of this functions have been taken over from Linux driver /drivers/usb/serial/ch341.c -static int32_t ch341_set_lcr ( cdch_interface_t* p_cdc, uint8_t lcr, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) -{ - /* - * Chip versions before version 0x30 as read using - * CH341_REQ_READ_VERSION used separate registers for line control - * (stop bits, parity and word length). Version 0x30 and above use - * CH341_REG_LCR only and CH341_REG_LCR2 is always set to zero. - */ - if ( p_cdc->ch34x.version < 0x30 ) - return 0; - - return ch341_write_reg ( p_cdc, CH341_REG_LCR2 << 8 | CH341_REG_LCR, lcr, complete_cb, user_data ); -} - -// set handshake (modem controls) -// Parts of this functions have been taken over from Linux driver /drivers/usb/serial/ch341.c -static int32_t ch341_set_handshake ( cdch_interface_t* p_cdc, uint8_t control, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) -{ - return ch341_control_out ( p_cdc, CH341_REQ_MODEM_CTRL, /* value */ ~control, /* index */ 0, complete_cb, user_data ); -} - -// detect quirks (special versions of CH34x) -// Parts of this functions have been taken over from Linux driver /drivers/usb/serial/ch341.c -static int32_t ch341_detect_quirks ( tuh_xfer_t* xfer, cdch_interface_t* p_cdc, uint8_t step, uint8_t *buffer, uint16_t buffersize, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) -{ - /* - * A subset of CH34x devices does not support all features. The - * prescaler is limited and there is no support for sending a RS232 - * break condition. A read failure when trying to set up the latter is - * used to detect these devices. - */ - switch ( step ) + for ( uint8_t i=0; ich34x.quirks = 0; - return ch341_read_reg_request ( p_cdc, CH341_REG_BREAK, buffer, buffersize, complete_cb, user_data ); - break; - case 2: - if ( xfer->result != XFER_RESULT_SUCCESS ) - p_cdc->ch34x.quirks |= CH341_QUIRK_LIMITED_PRESCALER | CH341_QUIRK_SIMULATE_BREAK; - return true; - break; - default: - TU_ASSERT ( false ); // suspicious step - break; + const cdch_interface_t* p_cdc = &cdch_data[i]; + if ( p_cdc->daddr == xfer->daddr ) return p_cdc->bInterfaceNumber; } + + return INTERFACE_INVALID_NUMBER; } // internal control complete to update state such as line state, encoding -// CH34x needs a special interface recovery due to abnormal wIndex usage -static void ch34x_control_complete(tuh_xfer_t* xfer) +static void ch34x_control_complete ( tuh_xfer_t* xfer ) { - uint8_t const itf_num = (uint8_t)( ( xfer->user_data & 0xff00 ) >> 8 ); + uint8_t const itf_num = ch34x_xfer_get_itf_num ( xfer ); uint8_t const idx = tuh_cdc_itf_get_index ( xfer->daddr, itf_num ); cdch_interface_t *p_cdc = get_itf ( idx ); + uint16_t value = tu_le16toh ( xfer->setup->wValue ); TU_ASSERT ( p_cdc, ); TU_ASSERT ( p_cdc->serial_drid == SERIAL_DRIVER_CH34X, ); // ch34x_control_complete is only used for CH34x - if (xfer->result == XFER_RESULT_SUCCESS) { - switch (xfer->setup->bRequest) { - case CH341_REQ_WRITE_REG: { // register write request - switch ( tu_le16toh ( xfer->setup->wValue ) ) { - case ( CH341_REG_DIVISOR << 8 | CH341_REG_PRESCALER ): { // baudrate write - p_cdc->line_coding.bit_rate = p_cdc->ch34x.baud_rate; + if ( xfer->result == XFER_RESULT_SUCCESS ) { + switch ( xfer->setup->bRequest ) { + case CH34X_REQ_WRITE_REG: { // register write request + switch ( value ) { + case ( 0x1312 ): { // baudrate write + p_cdc->line_coding.bit_rate = p_cdc->baudrate_requested; + #if CH34X_LOGS + TU_LOG_BAUDRATE("CDCh CH34x Control Complete ", p_cdc->line_coding.bit_rate); + #endif break; } default: { @@ -1512,6 +1401,20 @@ static void ch34x_control_complete(tuh_xfer_t* xfer) } break; } + case CH34X_REQ_MODEM_CTRL: { // set modem controls RTS/DTR request + if ( ~value & CH34X_BIT_RTS ) + p_cdc->line_state |= CDC_CONTROL_LINE_STATE_RTS; + else + p_cdc->line_state &= ~CDC_CONTROL_LINE_STATE_RTS; + if ( ~value & CH34X_BIT_DTR ) + p_cdc->line_state |= CDC_CONTROL_LINE_STATE_DTR; + else + p_cdc->line_state &= ~CDC_CONTROL_LINE_STATE_DTR; + #if CH34X_LOGS + TU_LOG_CONTROL_LINE_STATE("CDCh CH34x Control Complete ", p_cdc->line_state); + #endif + break; + } default: { TU_ASSERT(false, ); // unexpected request break; @@ -1523,118 +1426,161 @@ static void ch34x_control_complete(tuh_xfer_t* xfer) } } -static bool ch34x_set_baudrate ( cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) // do not confuse with ch341_set_baudrate +static bool ch34x_get_factor_divisor ( uint32_t baval, uint8_t *factor, uint8_t *divisor ) +{ // calc baudrate factor and divisor + uint8_t a; + uint8_t b; + uint32_t c; + + switch (baval) { + case 921600: + a = 0xf3; + b = 7; + break; + case 307200: + a = 0xd9; + b = 7; + break; + default: + if (baval > 6000000 / 255) { + b = 3; + c = 6000000; + } else if (baval > 750000 / 255) { + b = 2; + c = 750000; + } else if (baval > 93750 / 255) { + b = 1; + c = 93750; + } else { + b = 0; + c = 11719; + } + a = (unsigned char)(c / baval); + if (a == 0 || a == 0xFF) + return false; + if ((c / a - baval) > (baval - c / (a + 1))) + a++; + a = 256 - a; + break; + } + *factor = a; + *divisor = b; + + return true; +} + +static bool ch34x_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { - TU_LOG_DRV("CDC CH34x Set BaudRate = %lu\r\n", baudrate); - uint32_t baud_le = tu_htole32(baudrate); - p_cdc->ch34x.baud_rate = baudrate; + TU_ASSERT(false, false); // TODO + return false; +} + +static bool ch34x_set_baudrate ( cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) +{ + p_cdc->baudrate_requested = baudrate; p_cdc->user_control_cb = complete_cb; - return ch341_set_baudrate ( p_cdc, baud_le, complete_cb ? ch34x_control_complete : NULL, user_data ); + uint8_t factor, divisor; + TU_ASSERT ( ch34x_get_factor_divisor ( baudrate, &factor, &divisor ), false ); + TU_ASSERT ( ch34x_write_reg ( p_cdc, /* reg */ 0x1312, /* value */ (uint16_t)factor << 8 | 0x80 | divisor, + complete_cb ? ch34x_control_complete : NULL, user_data ), false ); + + return true; } static bool ch34x_set_modem_ctrl ( cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) { - TU_LOG_DRV("CDC CH34x Set Control Line State\r\n"); - // todo later - return false; + p_cdc->user_control_cb = complete_cb; + uint16_t control = 0; + if ( line_state & CDC_CONTROL_LINE_STATE_RTS ) + control |= CH34X_BIT_RTS; + if ( line_state & CDC_CONTROL_LINE_STATE_DTR ) + control |= CH34X_BIT_DTR; + TU_ASSERT ( ch34x_control_out ( p_cdc, /* request */ CH34X_REQ_MODEM_CTRL, /* value */ (uint8_t)~control, + /* index */ 0, complete_cb ? ch34x_control_complete : NULL, user_data ), false ); + return true; } static void ch34x_process_config ( tuh_xfer_t* xfer ) { - uintptr_t const state = xfer->user_data & 0xff; - // CH34x needs a special handling of bInterfaceNumber, because wIndex is used for other purposes and not for bInterfaceNumber - uint8_t const itf_num = (uint8_t)( ( xfer->user_data & 0xff00 ) >> 8 ); - uint8_t const idx = tuh_cdc_itf_get_index ( xfer->daddr, itf_num ); - cdch_interface_t *p_cdc = get_itf ( idx ); - uint8_t buffer [ CH34X_BUFFER_SIZE ]; - cdc_line_coding_t line_coding = CFG_TUH_CDC_LINE_CODING_ON_ENUM; + uint8_t const itf_num = ch34x_xfer_get_itf_num ( xfer ); + uintptr_t const state = xfer->user_data; + uint8_t const idx = tuh_cdc_itf_get_index ( xfer->daddr, itf_num ); + cdch_interface_t *p_cdc = get_itf ( idx ); + cdc_line_coding_t const line_coding = CFG_TUH_CDC_LINE_CODING_ON_ENUM_CH34X; + uint8_t buffer[2]; TU_ASSERT ( p_cdc, ); - if ( state == 0 ) { - // defaults - p_cdc->ch34x.baud_rate = DEFAULT_BAUD_RATE; - p_cdc->ch34x.mcr = 0; - p_cdc->ch34x.msr = 0; - p_cdc->ch34x.quirks = 0; - p_cdc->ch34x.version = 0; - /* - * Some CH340 devices appear unable to change the initial LCR - * settings, so set a sane 8N1 default. - */ - p_cdc->ch34x.lcr = CH341_LCR_ENABLE_RX | CH341_LCR_ENABLE_TX | CH341_LCR_CS8; - } - // This process flow has been taken over from Linux driver /drivers/usb/serial/ch341.c switch ( state ) { - case CONFIG_CH34X_STEP1: // request version read - TU_ASSERT ( ch341_control_in ( p_cdc, /* request */ CH341_REQ_READ_VERSION, /* value */ 0, /* index */ 0, buffer, CH34X_BUFFER_SIZE, ch34x_process_config, CONFIG_CH34X_STEP2 ), ); + case CONFIG_CH34X_READ_VERSION: // request version read + #if CH34X_LOGS + TU_LOG_DRV ( "[%u] CDCh CH34x Process Config started\r\n", p_cdc->daddr ); + #endif + TU_ASSERT ( ch34x_control_in ( p_cdc, /* request */ CH34X_REQ_READ_VERSION, /* value */ 0, + /* index */ 0, buffer, 2, ch34x_process_config, CONFIG_CH34X_SERIAL_INIT ), ); break; - case CONFIG_CH34X_STEP2: // handle version read data, request to init CH34x - p_cdc->ch34x.version = xfer->buffer[0]; - TU_LOG_DRV ( "Chip version=%02x\r\n", p_cdc->ch34x.version ); - TU_ASSERT ( ch341_control_out ( p_cdc, /* request */ CH341_REQ_SERIAL_INIT, /* value */ 0, /* index */ 0, ch34x_process_config, CONFIG_CH34X_STEP3 ), ); - break; - case CONFIG_CH34X_STEP3: // set baudrate with default values (see above) - TU_ASSERT ( ch341_set_baudrate ( p_cdc, p_cdc->ch34x.baud_rate, ch34x_process_config, CONFIG_CH34X_STEP4 ) > 0, ); - break; - case CONFIG_CH34X_STEP4: // set line controls with default values (see above) - TU_ASSERT ( ch341_set_lcr ( p_cdc, p_cdc->ch34x.lcr, ch34x_process_config, CONFIG_CH34X_STEP5 ) > 0, ); - break; - case CONFIG_CH34X_STEP5: // set handshake RTS/DTR - TU_ASSERT ( ch341_set_handshake ( p_cdc, p_cdc->ch34x.mcr, ch34x_process_config, CONFIG_CH34X_STEP6 ) > 0, ); - break; - case CONFIG_CH34X_STEP6: // detect quirks step 1 - TU_ASSERT ( ch341_detect_quirks ( xfer, p_cdc, /* step */ 1, buffer, CH34X_BUFFER_SIZE, ch34x_process_config, CONFIG_CH34X_STEP7 ) > 0, ); - break; - case CONFIG_CH34X_STEP7: // detect quirks step 2 and set baudrate with configured values - TU_ASSERT ( ch341_detect_quirks ( xfer, p_cdc, /* step */ 2, NULL, 0, NULL, 0 ) > 0, ); -#ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM - TU_ASSERT ( ch34x_set_baudrate ( p_cdc, line_coding.bit_rate, ch34x_process_config, CONFIG_CH34X_STEP8 ), ); -#else - TU_ATTR_FALLTHROUGH; -#endif - break; - case CONFIG_CH34X_STEP8: // set data/stop bit quantities, parity -#ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM - p_cdc->ch34x.lcr = CH341_LCR_ENABLE_RX | CH341_LCR_ENABLE_TX; + case CONFIG_CH34X_SERIAL_INIT: { // handle version read data, request to init CH34x with line_coding and baudrate + uint8_t version = xfer->buffer[0]; + #if CH34X_LOGS + TU_LOG_DRV ( "[%u] CDCh CH34x Chip version=%02x\r\n", p_cdc->daddr, version ); + #endif + // only versions >= 0x30 are tested, below 0x30 seems having other programming, see WCH vendor, linux kernel and FreeBSD drivers + TU_ASSERT ( version >= 0x30, ); + uint8_t factor, divisor; + TU_ASSERT ( ch34x_get_factor_divisor ( line_coding.bit_rate, &factor, &divisor ), ); + uint8_t lcr = CH34X_LCR_ENABLE_RX | CH34X_LCR_ENABLE_TX; switch ( line_coding.data_bits ) { case 5: - p_cdc->ch34x.lcr |= CH341_LCR_CS5; + lcr |= CH34X_LCR_CS5; break; case 6: - p_cdc->ch34x.lcr |= CH341_LCR_CS6; + lcr |= CH34X_LCR_CS6; break; case 7: - p_cdc->ch34x.lcr |= CH341_LCR_CS7; + lcr |= CH34X_LCR_CS7; break; case 8: - p_cdc->ch34x.lcr |= CH341_LCR_CS8; + lcr |= CH34X_LCR_CS8; break; default: TU_ASSERT ( false, ); // not supported data_bits - p_cdc->ch34x.lcr |= CH341_LCR_CS8; + lcr |= CH34X_LCR_CS8; break; } if ( line_coding.parity != CDC_LINE_CODING_PARITY_NONE ) { - p_cdc->ch34x.lcr |= CH341_LCR_ENABLE_PAR; + lcr |= CH34X_LCR_ENABLE_PAR; if ( line_coding.parity == CDC_LINE_CODING_PARITY_EVEN || line_coding.parity == CDC_LINE_CODING_PARITY_SPACE ) - p_cdc->ch34x.lcr |= CH341_LCR_PAR_EVEN; + lcr |= CH34X_LCR_PAR_EVEN; if ( line_coding.parity == CDC_LINE_CODING_PARITY_MARK || line_coding.parity == CDC_LINE_CODING_PARITY_SPACE ) - p_cdc->ch34x.lcr |= CH341_LCR_MARK_SPACE; + lcr |= CH34X_LCR_MARK_SPACE; } TU_ASSERT ( line_coding.stop_bits == CDC_LINE_CODING_STOP_BITS_1 || line_coding.stop_bits == CDC_LINE_CODING_STOP_BITS_2, ); // not supported 1.5 stop bits if ( line_coding.stop_bits == CDC_LINE_CODING_STOP_BITS_2 ) - p_cdc->ch34x.lcr |= CH341_LCR_STOP_BITS_2; - TU_ASSERT ( ch341_set_lcr ( p_cdc, p_cdc->ch34x.lcr, ch34x_process_config, CONFIG_CH34X_COMPLETE ) > 0, ); -#else - TU_ATTR_FALLTHROUGH; -#endif + lcr |= CH34X_LCR_STOP_BITS_2; + TU_ASSERT ( ch34x_control_out ( p_cdc, /* request */ CH34X_REQ_SERIAL_INIT, /* value */ (uint16_t)lcr << 8 | 0x9c, + /* index */ (uint16_t)factor << 8 | 0x80 | divisor, ch34x_process_config, CONFIG_CH34X_SPECIAL_REG_WRITE ), ); + break; + } + case CONFIG_CH34X_SPECIAL_REG_WRITE: // do special reg write, purpose unknown, overtaken from WCH driver + TU_ASSERT ( ch34x_write_reg ( p_cdc, /* reg */ 0x0f2c, /* value */ 0x0007, ch34x_process_config, CONFIG_CH34X_FLOW_CONTROL ), ); + break; + case CONFIG_CH34X_FLOW_CONTROL: // no hardware flow control + TU_ASSERT ( ch34x_write_reg ( p_cdc, /* reg */ 0x2727, /* value */ 0x0000, ch34x_process_config, CONFIG_CH34X_MODEM_CONTROL ), ); + break; + case CONFIG_CH34X_MODEM_CONTROL: // !always! set modem controls RTS/DTR (CH34x has no reset state after CH34X_REQ_SERIAL_INIT) + TU_ASSERT ( ch34x_set_modem_ctrl ( p_cdc, CFG_TUH_CDC_LINE_CONTROL_ON_ENUM, ch34x_process_config, CONFIG_CH34X_COMPLETE ), ); + break; + case CONFIG_CH34X_COMPLETE: + p_cdc->line_coding = line_coding; // CONFIG_CH34X_SERIAL_INIT not handled by ch34x_control_complete + #if CH34X_LOGS + TU_LOG_DRV("CDCh CH34x Process Config Complete\r\n"); + TU_LOG_LINE_CODING(" ", p_cdc->line_coding); + TU_LOG_CONTROL_LINE_STATE(" ", p_cdc->line_state); + #endif + set_config_complete ( p_cdc, idx, itf_num ); + break; + default: + TU_ASSERT ( false, ); break; - case CONFIG_CH34X_COMPLETE: - set_config_complete ( p_cdc, idx, itf_num ); - break; - default: - TU_ASSERT ( false, ); - break; } } diff --git a/src/class/cdc/cdc_host.h b/src/class/cdc/cdc_host.h index 9e5edd94e..8e3a2352a 100644 --- a/src/class/cdc/cdc_host.h +++ b/src/class/cdc/cdc_host.h @@ -37,7 +37,7 @@ // Class Driver Configuration //--------------------------------------------------------------------+ -// Set Line Control state on enumeration/mounted: DTR ( bit 0), RTS (bit 1) +// Set Line Control state on enumeration/mounted, refer enums CDC_CONTROL_LINE_STATE_RTS, CDC_CONTROL_LINE_STATE_DTR #ifndef CFG_TUH_CDC_LINE_CONTROL_ON_ENUM #define CFG_TUH_CDC_LINE_CONTROL_ON_ENUM 0 #endif @@ -142,7 +142,7 @@ bool tuh_cdc_read_clear (uint8_t idx); // - The function will return true if transfer is successful, false otherwise. //--------------------------------------------------------------------+ -// Request to Set Control Line State: DTR (bit 0), RTS (bit 1) +// Request to Set Control Line State, refer enums CDC_CONTROL_LINE_STATE_RTS, CDC_CONTROL_LINE_STATE_DTR bool tuh_cdc_set_control_line_state(uint8_t idx, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data); // Request to set baudrate diff --git a/src/class/cdc/serial/ch34x.h b/src/class/cdc/serial/ch34x.h index 94e18b252..262e012fd 100644 --- a/src/class/cdc/serial/ch34x.h +++ b/src/class/cdc/serial/ch34x.h @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2023 Heiko Kuester (tinyusb.org) + * Copyright (c) 2023 IngHK Heiko Kuester (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 @@ -27,87 +27,34 @@ #ifndef _CH34X_H_ #define _CH34X_H_ -#include - -#define BIT(nr) ( (uint32_t)1 << (nr) ) - -#define CH34X_BUFFER_SIZE 2 - -// The following defines have been taken over from Linux driver /drivers/usb/serial/ch341.c - -#define DEFAULT_BAUD_RATE 9600 - -/* flags for IO-Bits */ -#define CH341_BIT_RTS (1 << 6) -#define CH341_BIT_DTR (1 << 5) - -/******************************/ -/* interrupt pipe definitions */ -/******************************/ -/* always 4 interrupt bytes */ -/* first irq byte normally 0x08 */ -/* second irq byte base 0x7d + below */ -/* third irq byte base 0x94 + below */ -/* fourth irq byte normally 0xee */ - -/* second interrupt byte */ -#define CH341_MULT_STAT 0x04 /* multiple status since last interrupt event */ - -/* status returned in third interrupt answer byte, inverted in data - from irq */ -#define CH341_BIT_CTS 0x01 -#define CH341_BIT_DSR 0x02 -#define CH341_BIT_RI 0x04 -#define CH341_BIT_DCD 0x08 -#define CH341_BITS_MODEM_STAT 0x0f /* all bits */ - -/* Break support - the information used to implement this was gleaned from - * the Net/FreeBSD uchcom.c driver by Takanori Watanabe. Domo arigato. - */ +// set line_coding @ enumeration +#ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM +#define CFG_TUH_CDC_LINE_CODING_ON_ENUM_CH34X CFG_TUH_CDC_LINE_CODING_ON_ENUM +#else // this default is necessary to work properly +#define CFG_TUH_CDC_LINE_CODING_ON_ENUM_CH34X { 9600, CDC_LINE_CONDING_STOP_BITS_1, CDC_LINE_CODING_PARITY_NONE, 8 } +#endif // USB requests -#define CH341_REQ_READ_VERSION 0x5F // dec 95 -#define CH341_REQ_WRITE_REG 0x9A -#define CH341_REQ_READ_REG 0x95 -#define CH341_REQ_SERIAL_INIT 0xA1 -#define CH341_REQ_MODEM_CTRL 0xA4 +#define CH34X_REQ_READ_VERSION 0x5F // dec 95 +#define CH34X_REQ_WRITE_REG 0x9A // dec 154 +#define CH34X_REQ_READ_REG 0x95 // dec 149 +#define CH34X_REQ_SERIAL_INIT 0xA1 // dec 161 +#define CH34X_REQ_MODEM_CTRL 0xA4 // dev 164 -// CH34x registers -#define CH341_REG_BREAK 0x05 -#define CH341_REG_PRESCALER 0x12 -#define CH341_REG_DIVISOR 0x13 -#define CH341_REG_LCR 0x18 -#define CH341_REG_LCR2 0x25 - -#define CH341_NBREAK_BITS 0x01 +// modem control bits +#define CH34X_BIT_RTS ( 1 << 6 ) +#define CH34X_BIT_DTR ( 1 << 5 ) // line control bits -#define CH341_LCR_ENABLE_RX 0x80 -#define CH341_LCR_ENABLE_TX 0x40 -#define CH341_LCR_MARK_SPACE 0x20 -#define CH341_LCR_PAR_EVEN 0x10 -#define CH341_LCR_ENABLE_PAR 0x08 -#define CH341_LCR_STOP_BITS_2 0x04 -#define CH341_LCR_CS8 0x03 -#define CH341_LCR_CS7 0x02 -#define CH341_LCR_CS6 0x01 -#define CH341_LCR_CS5 0x00 - -#define CH341_QUIRK_LIMITED_PRESCALER BIT(0) -#define CH341_QUIRK_SIMULATE_BREAK BIT(1) - -#define CH341_CLKRATE 48000000 -#define CH341_CLK_DIV(ps, fact) (1 << (12 - 3 * (ps) - (fact))) -#define CH341_MIN_RATE(ps) (CH341_CLKRATE / (CH341_CLK_DIV((ps), 1) * 512)) - -/* Supported range is 46 to 3000000 bps. */ -#define CH341_MIN_BPS DIV_ROUND_UP(CH341_CLKRATE, CH341_CLK_DIV(0, 0) * 256) -#define CH341_MAX_BPS (CH341_CLKRATE / (CH341_CLK_DIV(3, 0) * 2)) - -#define DIV_ROUND_UP __KERNEL_DIV_ROUND_UP -#define __KERNEL_DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) - -// error codes -#define EINVAL 22 /* Invalid argument */ +#define CH34X_LCR_ENABLE_RX 0x80 +#define CH34X_LCR_ENABLE_TX 0x40 +#define CH34X_LCR_MARK_SPACE 0x20 +#define CH34X_LCR_PAR_EVEN 0x10 +#define CH34X_LCR_ENABLE_PAR 0x08 +#define CH34X_LCR_STOP_BITS_2 0x04 +#define CH34X_LCR_CS8 0x03 +#define CH34X_LCR_CS7 0x02 +#define CH34X_LCR_CS6 0x01 +#define CH34X_LCR_CS5 0x00 #endif /* _CH34X_H_ */ From 07e3d5c69192b1c45d52fc9760ab0ee65d8b0f0c Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 16 Jan 2024 13:16:53 +0700 Subject: [PATCH 052/454] fix number of endpoint for ch340x, also open notification even not used for now --- src/class/cdc/cdc_host.c | 67 +++++++++++++++++++----------------- src/class/cdc/serial/ch34x.h | 6 ++-- 2 files changed, 38 insertions(+), 35 deletions(-) diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 91e35ec8c..f7213d558 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -471,9 +471,9 @@ bool tuh_cdc_set_control_line_state(uint8_t idx, uint16_t line_state, tuh_xfer_c TU_VERIFY(p_cdc && p_cdc->serial_drid < SERIAL_DRIVER_COUNT); cdch_serial_driver_t const* driver = &serial_drivers[p_cdc->serial_drid]; - if ( complete_cb ) { + if (complete_cb) { return driver->set_control_line_state(p_cdc, line_state, complete_cb, user_data); - }else { + } else { // blocking xfer_result_t result = XFER_RESULT_INVALID; bool ret = driver->set_control_line_state(p_cdc, line_state, complete_cb, (uintptr_t) &result); @@ -494,9 +494,9 @@ bool tuh_cdc_set_baudrate(uint8_t idx, uint32_t baudrate, tuh_xfer_cb_t complete TU_VERIFY(p_cdc && p_cdc->serial_drid < SERIAL_DRIVER_COUNT); cdch_serial_driver_t const* driver = &serial_drivers[p_cdc->serial_drid]; - if ( complete_cb ) { + if (complete_cb) { return driver->set_baudrate(p_cdc, baudrate, complete_cb, user_data); - }else { + } else { // blocking xfer_result_t result = XFER_RESULT_INVALID; bool ret = driver->set_baudrate(p_cdc, baudrate, complete_cb, (uintptr_t) &result); @@ -512,16 +512,15 @@ bool tuh_cdc_set_baudrate(uint8_t idx, uint32_t baudrate, tuh_xfer_cb_t complete } } -bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ +bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { cdch_interface_t* p_cdc = get_itf(idx); // only ACM support this set line coding request TU_VERIFY(p_cdc && p_cdc->serial_drid == SERIAL_DRIVER_ACM); TU_VERIFY(p_cdc->acm_capability.support_line_request); - if ( complete_cb ) { + if (complete_cb) { return acm_set_line_coding(p_cdc, line_coding, complete_cb, user_data); - }else { + } else { // blocking xfer_result_t result = XFER_RESULT_INVALID; bool ret = acm_set_line_coding(p_cdc, line_coding, complete_cb, (uintptr_t) &result); @@ -711,7 +710,6 @@ static bool acm_open(uint8_t daddr, tusb_desc_interface_t const* itf_desc, uint1 cdch_interface_t* p_cdc = make_new_itf(daddr, itf_desc); TU_VERIFY(p_cdc); - p_cdc->serial_drid = SERIAL_DRIVER_ACM; //------------- Control Interface -------------// @@ -881,7 +879,6 @@ static bool ftdi_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint TU_VERIFY(p_cdc); TU_LOG_DRV("FTDI opened\r\n"); - p_cdc->serial_drid = SERIAL_DRIVER_FTDI; // endpoint pair @@ -921,8 +918,7 @@ static bool ftdi_sio_reset(cdch_interface_t* p_cdc, tuh_xfer_cb_t complete_cb, u return ftdi_sio_set_request(p_cdc, FTDI_SIO_RESET, FTDI_SIO_RESET_SIO, complete_cb, user_data); } -static bool -ftdi_sio_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { +static bool ftdi_sio_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { TU_LOG_DRV("CDC FTDI Set Control Line State\r\n"); p_cdc->user_control_cb = complete_cb; TU_ASSERT(ftdi_sio_set_request(p_cdc, FTDI_SIO_MODEM_CTRL, 0x0300 | line_state, @@ -1171,26 +1167,34 @@ enum { CONFIG_CH34X_COMPLETE }; -static bool ch34x_open ( uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len ) { - // CH34x Interface includes 1 vendor interface + 3 bulk endpoints - TU_VERIFY ( itf_desc->bNumEndpoints == 3 ); - TU_VERIFY ( sizeof ( tusb_desc_interface_t ) + 2 * sizeof ( tusb_desc_endpoint_t ) <= max_len ); +static bool ch34x_open(uint8_t daddr, tusb_desc_interface_t const* itf_desc, uint16_t max_len) { + // CH34x Interface includes 1 vendor interface + 2 bulk + 1 interrupt endpoints + TU_VERIFY (itf_desc->bNumEndpoints == 3); + TU_VERIFY (sizeof(tusb_desc_interface_t) + 3 * sizeof(tusb_desc_endpoint_t) <= max_len); - cdch_interface_t *p_cdc = make_new_itf ( daddr, itf_desc ); - TU_VERIFY ( p_cdc ); + cdch_interface_t* p_cdc = make_new_itf(daddr, itf_desc); + TU_VERIFY (p_cdc); - TU_LOG_DRV ( "CH34x opened\r\n" ); + TU_LOG_DRV ("CH34x opened\r\n"); p_cdc->serial_drid = SERIAL_DRIVER_CH34X; - // endpoint pair - tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const *) tu_desc_next ( itf_desc ); + tusb_desc_endpoint_t const* desc_ep = (tusb_desc_endpoint_t const*) tu_desc_next(itf_desc); // data endpoints expected to be in pairs - return open_ep_stream_pair ( p_cdc, desc_ep ); + TU_ASSERT(open_ep_stream_pair(p_cdc, desc_ep)); + desc_ep += 2; + + // Interrupt endpoint: not used for now + TU_ASSERT(TUSB_DESC_ENDPOINT == tu_desc_type(desc_ep) && + TUSB_XFER_INTERRUPT == desc_ep->bmAttributes.xfer); + TU_ASSERT(tuh_edpt_open(daddr, desc_ep)); + p_cdc->ep_notif = desc_ep->bEndpointAddress; + + return true; } -static bool ch34x_set_request ( cdch_interface_t* p_cdc, uint8_t direction, uint8_t request, uint16_t value, uint16_t index, uint8_t* buffer, uint16_t length, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) -{ +static bool ch34x_set_request(cdch_interface_t* p_cdc, uint8_t direction, uint8_t request, uint16_t value, + uint16_t index, uint8_t* buffer, uint16_t length, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { tusb_control_request_t const request_setup = { .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_DEVICE, @@ -1198,17 +1202,17 @@ static bool ch34x_set_request ( cdch_interface_t* p_cdc, uint8_t direction, uint .direction = direction & 0x01u }, .bRequest = request, - .wValue = tu_htole16 ( value ), - .wIndex = tu_htole16 ( index ), - .wLength = tu_htole16 ( length ) + .wValue = tu_htole16 (value), + .wIndex = tu_htole16 (index), + .wLength = tu_htole16 (length) }; // use usbh enum buf since application variable does not live long enough uint8_t* enum_buf = NULL; - if ( buffer && length > 0 ) { + if (buffer && length > 0) { enum_buf = usbh_get_enum_buf(); - tu_memcpy_s ( enum_buf, CFG_TUH_ENUMERATION_BUFSIZE, buffer, length ); + tu_memcpy_s(enum_buf, CFG_TUH_ENUMERATION_BUFSIZE, buffer, length); } tuh_xfer_t xfer = { @@ -1218,11 +1222,10 @@ static bool ch34x_set_request ( cdch_interface_t* p_cdc, uint8_t direction, uint .buffer = enum_buf, .complete_cb = complete_cb, // CH34x needs a special handling of bInterfaceNumber, because wIndex is used for other purposes and not for bInterfaceNumber - .user_data = (uintptr_t)( ( p_cdc->bInterfaceNumber & 0xff ) << 8 ) | ( user_data & 0xff ) + .user_data = (uintptr_t) ((p_cdc->bInterfaceNumber & 0xff) << 8) | (user_data & 0xff) }; - return tuh_control_xfer ( &xfer ); - return false; + return tuh_control_xfer(&xfer); } static bool ch341_control_out ( cdch_interface_t* p_cdc, uint8_t request, uint16_t value, uint16_t index, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) { diff --git a/src/class/cdc/serial/ch34x.h b/src/class/cdc/serial/ch34x.h index 4a5e61bbd..cc3ac99fe 100644 --- a/src/class/cdc/serial/ch34x.h +++ b/src/class/cdc/serial/ch34x.h @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2023 Heiko Kuester (tinyusb.org) + * Copyright (c) 2023 Heiko Kuester * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -34,6 +34,7 @@ #define CH34X_BUFFER_SIZE 2 // The following defines have been taken over from Linux driver /drivers/usb/serial/ch341.c +// Note: updated driver can also be found in https://github.com/WCHSoftGroup/ch341ser_linux/tree/main/driver #define DEFAULT_BAUD_RATE 9600 @@ -53,8 +54,7 @@ /* second interrupt byte */ #define CH341_MULT_STAT 0x04 /* multiple status since last interrupt event */ -/* status returned in third interrupt answer byte, inverted in data - from irq */ +/* status returned in third interrupt answer byte, inverted in data from irq */ #define CH341_BIT_CTS 0x01 #define CH341_BIT_DSR 0x02 #define CH341_BIT_RI 0x04 From 46ac03ba8537a32ae2bf1f7d864879657b696f81 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 16 Jan 2024 17:45:16 +0700 Subject: [PATCH 053/454] change code style --- src/class/cdc/cdc_host.c | 97 +++++++++++++++++++--------------------- 1 file changed, 46 insertions(+), 51 deletions(-) diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 8ef26a7d9..5541b5dee 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -1291,25 +1291,22 @@ static void ch34x_control_complete(tuh_xfer_t* xfer) { if (xfer->result == XFER_RESULT_SUCCESS) { switch (xfer->setup->bRequest) { - case CH34X_REQ_WRITE_REG: { // register write request + case CH34X_REQ_WRITE_REG: + // register write request switch (value) { - case (0x1312): { // baudrate write + case (0x1312): + // baudrate write p_cdc->line_coding.bit_rate = p_cdc->baudrate_requested; - #if CH34X_LOGS - TU_LOG_BAUDRATE("CDCh CH34x Control Complete ", p_cdc->line_coding.bit_rate); - #endif break; - } - default: { + default: TU_ASSERT(false,); // unexpected register write break; - } } break; - } - case CH34X_REQ_MODEM_CTRL: { // set modem controls RTS/DTR request + case CH34X_REQ_MODEM_CTRL: + // set modem controls RTS/DTR request if (~value & CH34X_BIT_RTS) { p_cdc->line_state |= CDC_CONTROL_LINE_STATE_RTS; } else { @@ -1322,16 +1319,11 @@ static void ch34x_control_complete(tuh_xfer_t* xfer) { p_cdc->line_state &= (uint8_t ) ~CDC_CONTROL_LINE_STATE_DTR; } - #if CH34X_LOGS - TU_LOG_CONTROL_LINE_STATE("CDCh CH34x Control Complete ", p_cdc->line_state); - #endif break; - } - default: { + default: TU_ASSERT(false,); // unexpected request break; - } } xfer->complete_cb = p_cdc->user_control_cb; @@ -1393,33 +1385,31 @@ static bool ch34x_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t con return false; } -static bool -ch34x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, - uintptr_t user_data) { +static bool ch34x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { p_cdc->baudrate_requested = baudrate; p_cdc->user_control_cb = complete_cb; uint8_t factor, divisor; - TU_ASSERT (ch34x_get_factor_divisor(baudrate, &factor, &divisor), false); + TU_ASSERT (ch34x_get_factor_divisor(baudrate, &factor, &divisor)); uint16_t const value = (uint16_t ) (factor << 8 | 0x80 | divisor); - TU_ASSERT ( - ch34x_write_reg(p_cdc, /* reg */ 0x1312, /* value */ value, - complete_cb ? ch34x_control_complete : NULL, user_data), false); + TU_ASSERT (ch34x_write_reg(p_cdc, 0x1312, value, + complete_cb ? ch34x_control_complete : NULL, user_data)); return true; } -static bool -ch34x_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, - uintptr_t user_data) { +static bool ch34x_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { p_cdc->user_control_cb = complete_cb; uint16_t control = 0; - if (line_state & CDC_CONTROL_LINE_STATE_RTS) + if (line_state & CDC_CONTROL_LINE_STATE_RTS) { control |= CH34X_BIT_RTS; - if (line_state & CDC_CONTROL_LINE_STATE_DTR) + } + if (line_state & CDC_CONTROL_LINE_STATE_DTR) { control |= CH34X_BIT_DTR; - TU_ASSERT ( - ch34x_control_out(p_cdc, /* request */ CH34X_REQ_MODEM_CTRL, /* value */ (uint8_t) ~control, - /* index */ 0, complete_cb ? ch34x_control_complete : NULL, user_data), false); + } + TU_ASSERT (ch34x_control_out(p_cdc, CH34X_REQ_MODEM_CTRL, (uint8_t) ~control, 0, + complete_cb ? ch34x_control_complete : NULL, user_data)); return true; } @@ -1437,9 +1427,9 @@ static void ch34x_process_config(tuh_xfer_t* xfer) { #if CH34X_LOGS TU_LOG_DRV ( "[%u] CDCh CH34x Process Config started\r\n", p_cdc->daddr ); #endif - TU_ASSERT (ch34x_control_in(p_cdc, /* request */ CH34X_REQ_READ_VERSION, /* value */ 0, - /* index */ 0, buffer, 2, ch34x_process_config, CONFIG_CH34X_SERIAL_INIT),); + TU_ASSERT (ch34x_control_in(p_cdc, CH34X_REQ_READ_VERSION, 0, 0, buffer, 2, ch34x_process_config, CONFIG_CH34X_SERIAL_INIT),); break; + case CONFIG_CH34X_SERIAL_INIT: { // handle version read data, request to init CH34x with line_coding and baudrate uint8_t version = xfer->buffer[0]; #if CH34X_LOGS @@ -1468,46 +1458,51 @@ static void ch34x_process_config(tuh_xfer_t* xfer) { lcr |= CH34X_LCR_CS8; break; } + if (line_coding.parity != CDC_LINE_CODING_PARITY_NONE) { lcr |= CH34X_LCR_ENABLE_PAR; if (line_coding.parity == CDC_LINE_CODING_PARITY_EVEN || - line_coding.parity == CDC_LINE_CODING_PARITY_SPACE) + line_coding.parity == CDC_LINE_CODING_PARITY_SPACE) { lcr |= CH34X_LCR_PAR_EVEN; + } if (line_coding.parity == CDC_LINE_CODING_PARITY_MARK || - line_coding.parity == CDC_LINE_CODING_PARITY_SPACE) + line_coding.parity == CDC_LINE_CODING_PARITY_SPACE) { lcr |= CH34X_LCR_MARK_SPACE; + } } TU_ASSERT (line_coding.stop_bits == CDC_LINE_CODING_STOP_BITS_1 || line_coding.stop_bits == CDC_LINE_CODING_STOP_BITS_2,); // not supported 1.5 stop bits - if (line_coding.stop_bits == CDC_LINE_CODING_STOP_BITS_2) + if (line_coding.stop_bits == CDC_LINE_CODING_STOP_BITS_2) { lcr |= CH34X_LCR_STOP_BITS_2; - TU_ASSERT (ch34x_control_out(p_cdc, /* request */ CH34X_REQ_SERIAL_INIT, /* value */ - (uint16_t) (lcr << 8 | 0x9c), - /* index */ (uint16_t) (factor << 8 | 0x80 | divisor), ch34x_process_config, - CONFIG_CH34X_SPECIAL_REG_WRITE),); + } + TU_ASSERT (ch34x_control_out(p_cdc, CH34X_REQ_SERIAL_INIT, (uint16_t) (lcr << 8 | 0x9c), (uint16_t) (factor << 8 | 0x80 | divisor), + ch34x_process_config, CONFIG_CH34X_SPECIAL_REG_WRITE),); break; } - case CONFIG_CH34X_SPECIAL_REG_WRITE: // do special reg write, purpose unknown, overtaken from WCH driver - TU_ASSERT (ch34x_write_reg(p_cdc, /* reg */ 0x0f2c, /* value */ 0x0007, ch34x_process_config, - CONFIG_CH34X_FLOW_CONTROL),); + + case CONFIG_CH34X_SPECIAL_REG_WRITE: + // do special reg write, purpose unknown, overtaken from WCH driver + TU_ASSERT (ch34x_write_reg(p_cdc, 0x0f2c, 0x0007, ch34x_process_config, CONFIG_CH34X_FLOW_CONTROL),); break; - case CONFIG_CH34X_FLOW_CONTROL: // no hardware flow control - TU_ASSERT (ch34x_write_reg(p_cdc, /* reg */ 0x2727, /* value */ 0x0000, ch34x_process_config, - CONFIG_CH34X_MODEM_CONTROL),); + + case CONFIG_CH34X_FLOW_CONTROL: + // no hardware flow control + TU_ASSERT (ch34x_write_reg(p_cdc, 0x2727, 0x0000, ch34x_process_config, CONFIG_CH34X_MODEM_CONTROL),); break; - case CONFIG_CH34X_MODEM_CONTROL: // !always! set modem controls RTS/DTR (CH34x has no reset state after CH34X_REQ_SERIAL_INIT) - TU_ASSERT (ch34x_set_modem_ctrl(p_cdc, CFG_TUH_CDC_LINE_CONTROL_ON_ENUM, ch34x_process_config, - CONFIG_CH34X_COMPLETE),); + + case CONFIG_CH34X_MODEM_CONTROL: + // !always! set modem controls RTS/DTR (CH34x has no reset state after CH34X_REQ_SERIAL_INIT) + TU_ASSERT (ch34x_set_modem_ctrl(p_cdc, CFG_TUH_CDC_LINE_CONTROL_ON_ENUM, ch34x_process_config, CONFIG_CH34X_COMPLETE),); break; + case CONFIG_CH34X_COMPLETE: p_cdc->line_coding = line_coding; // CONFIG_CH34X_SERIAL_INIT not handled by ch34x_control_complete #if CH34X_LOGS TU_LOG_DRV("CDCh CH34x Process Config Complete\r\n"); - TU_LOG_LINE_CODING(" ", p_cdc->line_coding); - TU_LOG_CONTROL_LINE_STATE(" ", p_cdc->line_state); #endif set_config_complete(p_cdc, idx, itf_num); break; + default: TU_ASSERT (false,); break; From 482a8068a51025ee8c31ccdb4355801c185172cc Mon Sep 17 00:00:00 2001 From: IngHK Date: Tue, 16 Jan 2024 14:51:04 +0100 Subject: [PATCH 054/454] change code style and code cleanup --- src/class/cdc/cdc_host.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 5541b5dee..4cecc79a1 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -1260,13 +1260,13 @@ static bool ch34x_control_in(cdch_interface_t* p_cdc, uint8_t request, uint16_t } static bool ch34x_write_reg(cdch_interface_t* p_cdc, uint16_t reg, uint16_t value, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { - return ch34x_control_out(p_cdc, CH34X_REQ_WRITE_REG, /* value */ reg, /* index */ value, complete_cb, user_data); + return ch34x_control_out(p_cdc, CH34X_REQ_WRITE_REG, reg, value, complete_cb, user_data); } //static bool ch34x_read_reg_request ( cdch_interface_t* p_cdc, uint16_t reg, // uint8_t *buffer, uint16_t buffersize, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) //{ -// return ch34x_control_in ( p_cdc, CH34X_REQ_READ_REG, reg, /* index */ 0, buffer, buffersize, complete_cb, user_data ); +// return ch34x_control_in ( p_cdc, CH34X_REQ_READ_REG, reg, 0, buffer, buffersize, complete_cb, user_data ); //} uint8_t ch34x_xfer_get_itf_num(tuh_xfer_t* xfer) { @@ -1327,7 +1327,9 @@ static void ch34x_control_complete(tuh_xfer_t* xfer) { } xfer->complete_cb = p_cdc->user_control_cb; - if (xfer->complete_cb)xfer->complete_cb(xfer); + if (xfer->complete_cb) { + xfer->complete_cb(xfer); + } } } @@ -1363,8 +1365,12 @@ static bool ch34x_get_factor_divisor(uint32_t baval, uint8_t* factor, uint8_t* d c = 11719; } a = (unsigned char) (c / baval); - if (a == 0 || a == 0xFF) return false; - if ((c / a - baval) > (baval - c / (a + 1))) a++; + if (a == 0 || a == 0xFF) { + return false; + } + if ((c / a - baval) > (baval - c / (a + 1))) { + a++; + } a = (uint8_t) (256 - a); break; } @@ -1425,7 +1431,7 @@ static void ch34x_process_config(tuh_xfer_t* xfer) { switch (state) { case CONFIG_CH34X_READ_VERSION: // request version read #if CH34X_LOGS - TU_LOG_DRV ( "[%u] CDCh CH34x Process Config started\r\n", p_cdc->daddr ); + TU_LOG_DRV ( "[%u] CDCh CH34x Process Config started\r\n", p_cdc->daddr ); #endif TU_ASSERT (ch34x_control_in(p_cdc, CH34X_REQ_READ_VERSION, 0, 0, buffer, 2, ch34x_process_config, CONFIG_CH34X_SERIAL_INIT),); break; @@ -1433,7 +1439,7 @@ static void ch34x_process_config(tuh_xfer_t* xfer) { case CONFIG_CH34X_SERIAL_INIT: { // handle version read data, request to init CH34x with line_coding and baudrate uint8_t version = xfer->buffer[0]; #if CH34X_LOGS - TU_LOG_DRV ( "[%u] CDCh CH34x Chip version=%02x\r\n", p_cdc->daddr, version ); + TU_LOG_DRV("[%u] CDCh CH34x Chip version=%02x\r\n", p_cdc->daddr, version); #endif // only versions >= 0x30 are tested, below 0x30 seems having other programming, see WCH vendor, linux kernel and FreeBSD drivers TU_ASSERT (version >= 0x30,); @@ -1470,8 +1476,8 @@ static void ch34x_process_config(tuh_xfer_t* xfer) { lcr |= CH34X_LCR_MARK_SPACE; } } - TU_ASSERT (line_coding.stop_bits == CDC_LINE_CODING_STOP_BITS_1 || line_coding.stop_bits == - CDC_LINE_CODING_STOP_BITS_2,); // not supported 1.5 stop bits + TU_ASSERT (line_coding.stop_bits == CDC_LINE_CODING_STOP_BITS_1 || + line_coding.stop_bits == CDC_LINE_CODING_STOP_BITS_2,); // 1.5 stop bits not supported if (line_coding.stop_bits == CDC_LINE_CODING_STOP_BITS_2) { lcr |= CH34X_LCR_STOP_BITS_2; } @@ -1498,7 +1504,7 @@ static void ch34x_process_config(tuh_xfer_t* xfer) { case CONFIG_CH34X_COMPLETE: p_cdc->line_coding = line_coding; // CONFIG_CH34X_SERIAL_INIT not handled by ch34x_control_complete #if CH34X_LOGS - TU_LOG_DRV("CDCh CH34x Process Config Complete\r\n"); + TU_LOG_DRV("CDCh CH34x Process Config Complete\r\n"); #endif set_config_complete(p_cdc, idx, itf_num); break; From f221c0fb6683fc552febbb9a52300d66f031d275 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 17 Jan 2024 14:45:09 +0700 Subject: [PATCH 055/454] more clean up --- src/class/cdc/cdc_host.c | 28 ++++++++++------------------ src/class/cdc/serial/ch34x.h | 13 +++++++++++++ 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 4cecc79a1..faee062cf 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -670,6 +670,7 @@ bool cdch_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const *itf_d } static void set_config_complete(cdch_interface_t * p_cdc, uint8_t idx, uint8_t itf_num) { + TU_LOG_DRV("CDCh Set Configure complete\r\n"); if (tuh_cdc_mount_cb) tuh_cdc_mount_cb(idx); // Prepare for incoming data @@ -1176,8 +1177,6 @@ static void cp210x_process_config(tuh_xfer_t* xfer) { #if CFG_TUH_CDC_CH34X -#define CH34X_LOGS false - enum { CONFIG_CH34X_READ_VERSION = 0, CONFIG_CH34X_SERIAL_INIT, @@ -1247,14 +1246,13 @@ static bool ch34x_set_request(cdch_interface_t* p_cdc, uint8_t direction, uint8_ return tuh_control_xfer(&xfer); } -static bool ch34x_control_out(cdch_interface_t* p_cdc, uint8_t request, uint16_t value, uint16_t index, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) { - return ch34x_set_request(p_cdc, TUSB_DIR_OUT, request, value, index, /* buffer */ NULL, /* length */ 0, complete_cb, user_data); +static inline bool ch34x_control_out(cdch_interface_t* p_cdc, uint8_t request, uint16_t value, uint16_t index, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + return ch34x_set_request(p_cdc, TUSB_DIR_OUT, request, value, index, NULL, 0, complete_cb, user_data); } -static bool ch34x_control_in(cdch_interface_t* p_cdc, uint8_t request, uint16_t value, uint16_t index, - uint8_t* buffer, uint16_t buffersize, tuh_xfer_cb_t complete_cb, - uintptr_t user_data) { +static inline bool ch34x_control_in(cdch_interface_t* p_cdc, uint8_t request, uint16_t value, uint16_t index, + uint8_t* buffer, uint16_t buffersize, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return ch34x_set_request(p_cdc, TUSB_DIR_IN, request, value, index, buffer, buffersize, complete_cb, user_data); } @@ -1425,27 +1423,24 @@ static void ch34x_process_config(tuh_xfer_t* xfer) { uint8_t const idx = tuh_cdc_itf_get_index(xfer->daddr, itf_num); cdch_interface_t* p_cdc = get_itf(idx); cdc_line_coding_t const line_coding = CFG_TUH_CDC_LINE_CODING_ON_ENUM_CH34X; - uint8_t buffer[2]; + uint8_t buffer[2]; // TODO remove TU_ASSERT (p_cdc,); switch (state) { case CONFIG_CH34X_READ_VERSION: // request version read - #if CH34X_LOGS - TU_LOG_DRV ( "[%u] CDCh CH34x Process Config started\r\n", p_cdc->daddr ); - #endif + TU_LOG_DRV("[%u] CDCh CH34x attempt to read version\r\n", p_cdc->daddr); TU_ASSERT (ch34x_control_in(p_cdc, CH34X_REQ_READ_VERSION, 0, 0, buffer, 2, ch34x_process_config, CONFIG_CH34X_SERIAL_INIT),); break; case CONFIG_CH34X_SERIAL_INIT: { // handle version read data, request to init CH34x with line_coding and baudrate uint8_t version = xfer->buffer[0]; - #if CH34X_LOGS - TU_LOG_DRV("[%u] CDCh CH34x Chip version=%02x\r\n", p_cdc->daddr, version); - #endif + TU_LOG_DRV("[%u] CDCh CH34x Chip version = %02x\r\n", p_cdc->daddr, version); // only versions >= 0x30 are tested, below 0x30 seems having other programming, see WCH vendor, linux kernel and FreeBSD drivers TU_ASSERT (version >= 0x30,); uint8_t factor, divisor; TU_ASSERT (ch34x_get_factor_divisor(line_coding.bit_rate, &factor, &divisor),); uint8_t lcr = CH34X_LCR_ENABLE_RX | CH34X_LCR_ENABLE_TX; + switch (line_coding.data_bits) { case 5: lcr |= CH34X_LCR_CS5; @@ -1503,9 +1498,6 @@ static void ch34x_process_config(tuh_xfer_t* xfer) { case CONFIG_CH34X_COMPLETE: p_cdc->line_coding = line_coding; // CONFIG_CH34X_SERIAL_INIT not handled by ch34x_control_complete - #if CH34X_LOGS - TU_LOG_DRV("CDCh CH34x Process Config Complete\r\n"); - #endif set_config_complete(p_cdc, idx, itf_num); break; diff --git a/src/class/cdc/serial/ch34x.h b/src/class/cdc/serial/ch34x.h index 557e093a9..54b5b3560 100644 --- a/src/class/cdc/serial/ch34x.h +++ b/src/class/cdc/serial/ch34x.h @@ -27,6 +27,10 @@ #ifndef _CH34X_H_ #define _CH34X_H_ +// There is no official documentation for the CH34x chips. Reference can be found +// - https://github.com/WCHSoftGroup/ch341ser_linux +// - https://github.com/torvalds/linux/blob/master/drivers/usb/serial/ch341.c + // set line_coding @ enumeration #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM #define CFG_TUH_CDC_LINE_CODING_ON_ENUM_CH34X CFG_TUH_CDC_LINE_CODING_ON_ENUM @@ -41,6 +45,15 @@ #define CH34X_REQ_SERIAL_INIT 0xA1 // dec 161 #define CH34X_REQ_MODEM_CTRL 0xA4 // dev 164 +#define CH34X_REG_BREAK 0x05 +#define CH34X_REG_PRESCALER 0x12 +#define CH34X_REG_DIVISOR 0x13 +#define CH34X_REG_LCR 0x18 +#define CH34X_REG_LCR2 0x25 +#define CH34X_REG_MCR_MSR 0x06 +#define CH34X_REG_MCR_MSR2 0x07 +#define CH34X_NBREAK_BITS 0x01 + // modem control bits #define CH34X_BIT_RTS ( 1 << 6 ) #define CH34X_BIT_DTR ( 1 << 5 ) From 3968a0fff87c794266284af7901e334d122e894c Mon Sep 17 00:00:00 2001 From: IngHK Date: Wed, 17 Jan 2024 16:04:31 +0100 Subject: [PATCH 056/454] implemented ch34x_set_line_coding() and some code cleanup --- src/class/cdc/cdc_host.c | 177 +++++++++++++++++++++-------------- src/class/cdc/serial/ch34x.h | 7 ++ 2 files changed, 116 insertions(+), 68 deletions(-) diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index faee062cf..45a03a31d 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -1179,7 +1179,7 @@ static void cp210x_process_config(tuh_xfer_t* xfer) { enum { CONFIG_CH34X_READ_VERSION = 0, - CONFIG_CH34X_SERIAL_INIT, + CONFIG_CH34X_SET_LINE_CODING, CONFIG_CH34X_SPECIAL_REG_WRITE, CONFIG_CH34X_FLOW_CONTROL, CONFIG_CH34X_MODEM_CONTROL, @@ -1292,11 +1292,10 @@ static void ch34x_control_complete(tuh_xfer_t* xfer) { case CH34X_REQ_WRITE_REG: // register write request switch (value) { - case (0x1312): + case 0x1312: // baudrate write p_cdc->line_coding.bit_rate = p_cdc->baudrate_requested; break; - default: TU_ASSERT(false,); // unexpected register write break; @@ -1310,13 +1309,60 @@ static void ch34x_control_complete(tuh_xfer_t* xfer) { } else { p_cdc->line_state &= (uint8_t ) ~CDC_CONTROL_LINE_STATE_RTS; } - if (~value & CH34X_BIT_DTR) { p_cdc->line_state |= CDC_CONTROL_LINE_STATE_DTR; } else { p_cdc->line_state &= (uint8_t ) ~CDC_CONTROL_LINE_STATE_DTR; } + break; + case CH34X_REQ_SERIAL_INIT: + // serial init request (set line coding incl. baudrate) + p_cdc->line_coding.bit_rate = p_cdc->baudrate_requested; + uint8_t lcr = (uint8_t) (value >> 8); + TU_ASSERT (lcr & CH34X_LCR_ENABLE_RX && lcr & CH34X_LCR_ENABLE_TX,); // both have to be enabled + switch (lcr & CH34X_LCR_CS_MASK) { + case CH34X_LCR_CS5: + p_cdc->line_coding.data_bits = 5; + break; + case CH34X_LCR_CS6: + p_cdc->line_coding.data_bits = 6; + break; + case CH34X_LCR_CS7: + p_cdc->line_coding.data_bits = 7; + break; + case CH34X_LCR_CS8: + p_cdc->line_coding.data_bits = 8; + break; + default: + TU_ASSERT (false,); // unexpected data_bits lcr + break; + } + if (lcr & CH34X_LCR_STOP_BITS_2) { + p_cdc->line_coding.stop_bits = CDC_LINE_CODING_STOP_BITS_2; + } else { + p_cdc->line_coding.stop_bits = CDC_LINE_CODING_STOP_BITS_1; + } + switch (lcr & CH34X_LCR_PAR_MASK) { + case 0: + p_cdc->line_coding.parity = CDC_LINE_CODING_PARITY_NONE; + break; + case CH34X_LCR_ENABLE_PAR: + p_cdc->line_coding.parity = CDC_LINE_CODING_PARITY_ODD; + break; + case CH34X_LCR_ENABLE_PAR | CH34X_LCR_PAR_EVEN: + p_cdc->line_coding.parity = CDC_LINE_CODING_PARITY_EVEN; + break; + case CH34X_LCR_ENABLE_PAR | CH34X_LCR_MARK_SPACE: + p_cdc->line_coding.parity = CDC_LINE_CODING_PARITY_MARK; + break; + case CH34X_LCR_ENABLE_PAR | CH34X_LCR_MARK_SPACE | CH34X_LCR_PAR_EVEN: + p_cdc->line_coding.parity = CDC_LINE_CODING_PARITY_SPACE; + break; + default: + TU_ASSERT (false,); // unexpected parity lcr + break; + } break; default: @@ -1378,15 +1424,57 @@ static bool ch34x_get_factor_divisor(uint32_t baval, uint8_t* factor, uint8_t* d return true; } +// calc lcr register value (data bits, parity, stop bits) +static bool ch34x_get_lcr(cdc_line_coding_t const* line_coding, uint8_t *lcr) { + *lcr = CH34X_LCR_ENABLE_RX | CH34X_LCR_ENABLE_TX; + switch (line_coding->data_bits) { + case 5: + *lcr |= CH34X_LCR_CS5; + break; + case 6: + *lcr |= CH34X_LCR_CS6; + break; + case 7: + *lcr |= CH34X_LCR_CS7; + break; + case 8: + *lcr |= CH34X_LCR_CS8; + break; + default: + TU_ASSERT (false); // data_bits not supported + break; + } + TU_ASSERT (line_coding->parity == CDC_LINE_CODING_PARITY_NONE || // supported parities + line_coding->parity == CDC_LINE_CODING_PARITY_ODD || line_coding->parity == CDC_LINE_CODING_PARITY_EVEN || + line_coding->parity == CDC_LINE_CODING_PARITY_MARK || line_coding->parity == CDC_LINE_CODING_PARITY_SPACE); + if (line_coding->parity != CDC_LINE_CODING_PARITY_NONE) { + *lcr |= CH34X_LCR_ENABLE_PAR; + if (line_coding->parity == CDC_LINE_CODING_PARITY_EVEN || line_coding->parity == CDC_LINE_CODING_PARITY_SPACE) { + *lcr |= CH34X_LCR_PAR_EVEN; + } + if (line_coding->parity == CDC_LINE_CODING_PARITY_MARK || line_coding->parity == CDC_LINE_CODING_PARITY_SPACE) { + *lcr |= CH34X_LCR_MARK_SPACE; + } + } + TU_ASSERT (line_coding->stop_bits == CDC_LINE_CODING_STOP_BITS_1 || + line_coding->stop_bits == CDC_LINE_CODING_STOP_BITS_2); // not supported 1.5 stop bits + if (line_coding->stop_bits == CDC_LINE_CODING_STOP_BITS_2) { + *lcr |= CH34X_LCR_STOP_BITS_2; + } + + return true; +} + static bool ch34x_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { - // TODO implement later - (void) p_cdc; - (void) line_coding; - (void) complete_cb; - (void) user_data; - - return false; + p_cdc->baudrate_requested = line_coding->bit_rate; + p_cdc->user_control_cb = complete_cb; + uint8_t factor, divisor, lcr; + TU_ASSERT (ch34x_get_factor_divisor(line_coding->bit_rate, &factor, &divisor)); + TU_ASSERT (ch34x_get_lcr(line_coding, &lcr)); + TU_ASSERT (ch34x_control_out(p_cdc, CH34X_REQ_SERIAL_INIT, (uint16_t) (lcr << 8 | 0x9c), (uint16_t) (factor << 8 | 0x80 | divisor), + complete_cb ? ch34x_control_complete : NULL, user_data)); + return true; } static bool ch34x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, @@ -1398,7 +1486,6 @@ static bool ch34x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, uint16_t const value = (uint16_t ) (factor << 8 | 0x80 | divisor); TU_ASSERT (ch34x_write_reg(p_cdc, 0x1312, value, complete_cb ? ch34x_control_complete : NULL, user_data)); - return true; } @@ -1427,82 +1514,36 @@ static void ch34x_process_config(tuh_xfer_t* xfer) { TU_ASSERT (p_cdc,); switch (state) { - case CONFIG_CH34X_READ_VERSION: // request version read - TU_LOG_DRV("[%u] CDCh CH34x attempt to read version\r\n", p_cdc->daddr); - TU_ASSERT (ch34x_control_in(p_cdc, CH34X_REQ_READ_VERSION, 0, 0, buffer, 2, ch34x_process_config, CONFIG_CH34X_SERIAL_INIT),); + case CONFIG_CH34X_READ_VERSION: + // version read request + TU_LOG_DRV("[%u] CDCh CH34x attempt to read Chip Version\r\n", p_cdc->daddr); + TU_ASSERT (ch34x_control_in(p_cdc, CH34X_REQ_READ_VERSION, 0, 0, buffer, 2, ch34x_process_config, CONFIG_CH34X_SET_LINE_CODING),); break; - - case CONFIG_CH34X_SERIAL_INIT: { // handle version read data, request to init CH34x with line_coding and baudrate + case CONFIG_CH34X_SET_LINE_CODING: + // handle version read data, set CH34x line coding (incl. baudrate) uint8_t version = xfer->buffer[0]; - TU_LOG_DRV("[%u] CDCh CH34x Chip version = %02x\r\n", p_cdc->daddr, version); - // only versions >= 0x30 are tested, below 0x30 seems having other programming, see WCH vendor, linux kernel and FreeBSD drivers + TU_LOG_DRV("[%u] CDCh CH34x Chip Version = %02x\r\n", p_cdc->daddr, version); + // only versions >= 0x30 are tested, below 0x30 seems having other programming, see drivers from WCH vendor, Linux kernel and FreeBSD TU_ASSERT (version >= 0x30,); - uint8_t factor, divisor; - TU_ASSERT (ch34x_get_factor_divisor(line_coding.bit_rate, &factor, &divisor),); - uint8_t lcr = CH34X_LCR_ENABLE_RX | CH34X_LCR_ENABLE_TX; - - switch (line_coding.data_bits) { - case 5: - lcr |= CH34X_LCR_CS5; - break; - case 6: - lcr |= CH34X_LCR_CS6; - break; - case 7: - lcr |= CH34X_LCR_CS7; - break; - case 8: - lcr |= CH34X_LCR_CS8; - break; - default: - TU_ASSERT (false,); // not supported data_bits - lcr |= CH34X_LCR_CS8; - break; - } - - if (line_coding.parity != CDC_LINE_CODING_PARITY_NONE) { - lcr |= CH34X_LCR_ENABLE_PAR; - if (line_coding.parity == CDC_LINE_CODING_PARITY_EVEN || - line_coding.parity == CDC_LINE_CODING_PARITY_SPACE) { - lcr |= CH34X_LCR_PAR_EVEN; - } - if (line_coding.parity == CDC_LINE_CODING_PARITY_MARK || - line_coding.parity == CDC_LINE_CODING_PARITY_SPACE) { - lcr |= CH34X_LCR_MARK_SPACE; - } - } - TU_ASSERT (line_coding.stop_bits == CDC_LINE_CODING_STOP_BITS_1 || - line_coding.stop_bits == CDC_LINE_CODING_STOP_BITS_2,); // 1.5 stop bits not supported - if (line_coding.stop_bits == CDC_LINE_CODING_STOP_BITS_2) { - lcr |= CH34X_LCR_STOP_BITS_2; - } - TU_ASSERT (ch34x_control_out(p_cdc, CH34X_REQ_SERIAL_INIT, (uint16_t) (lcr << 8 | 0x9c), (uint16_t) (factor << 8 | 0x80 | divisor), - ch34x_process_config, CONFIG_CH34X_SPECIAL_REG_WRITE),); + TU_ASSERT (ch34x_set_line_coding(p_cdc, &line_coding, ch34x_process_config, CONFIG_CH34X_SPECIAL_REG_WRITE),); break; - } - case CONFIG_CH34X_SPECIAL_REG_WRITE: // do special reg write, purpose unknown, overtaken from WCH driver TU_ASSERT (ch34x_write_reg(p_cdc, 0x0f2c, 0x0007, ch34x_process_config, CONFIG_CH34X_FLOW_CONTROL),); break; - case CONFIG_CH34X_FLOW_CONTROL: // no hardware flow control TU_ASSERT (ch34x_write_reg(p_cdc, 0x2727, 0x0000, ch34x_process_config, CONFIG_CH34X_MODEM_CONTROL),); break; - case CONFIG_CH34X_MODEM_CONTROL: // !always! set modem controls RTS/DTR (CH34x has no reset state after CH34X_REQ_SERIAL_INIT) TU_ASSERT (ch34x_set_modem_ctrl(p_cdc, CFG_TUH_CDC_LINE_CONTROL_ON_ENUM, ch34x_process_config, CONFIG_CH34X_COMPLETE),); break; - case CONFIG_CH34X_COMPLETE: - p_cdc->line_coding = line_coding; // CONFIG_CH34X_SERIAL_INIT not handled by ch34x_control_complete set_config_complete(p_cdc, idx, itf_num); break; - default: - TU_ASSERT (false,); + TU_ASSERT (false,); // something gone wrong, should never reached break; } } diff --git a/src/class/cdc/serial/ch34x.h b/src/class/cdc/serial/ch34x.h index 54b5b3560..b4ed7420c 100644 --- a/src/class/cdc/serial/ch34x.h +++ b/src/class/cdc/serial/ch34x.h @@ -27,9 +27,13 @@ #ifndef _CH34X_H_ #define _CH34X_H_ +// For simplicity, only the name CH34X is used here, +// but specifically only CH340 and CH341 are supported. + // There is no official documentation for the CH34x chips. Reference can be found // - https://github.com/WCHSoftGroup/ch341ser_linux // - https://github.com/torvalds/linux/blob/master/drivers/usb/serial/ch341.c +// - https://github.com/freebsd/freebsd-src/blob/main/sys/dev/usb/serial/uchcom.c // set line_coding @ enumeration #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM @@ -45,6 +49,7 @@ #define CH34X_REQ_SERIAL_INIT 0xA1 // dec 161 #define CH34X_REQ_MODEM_CTRL 0xA4 // dev 164 +// registers #define CH34X_REG_BREAK 0x05 #define CH34X_REG_PRESCALER 0x12 #define CH34X_REG_DIVISOR 0x13 @@ -64,10 +69,12 @@ #define CH34X_LCR_MARK_SPACE 0x20 #define CH34X_LCR_PAR_EVEN 0x10 #define CH34X_LCR_ENABLE_PAR 0x08 +#define CH34X_LCR_PAR_MASK 0x38 // all parity bits #define CH34X_LCR_STOP_BITS_2 0x04 #define CH34X_LCR_CS8 0x03 #define CH34X_LCR_CS7 0x02 #define CH34X_LCR_CS6 0x01 #define CH34X_LCR_CS5 0x00 +#define CH34X_LCR_CS_MASK 0x03 // all CSx bits #endif /* _CH34X_H_ */ From 30eb35f17f1baa4698da0cd45dbc3dff8906d7c0 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 19 Jan 2024 01:06:24 +0700 Subject: [PATCH 057/454] - revert the use of serial init for set line coding - update ch34x_get_lcr and ch34x_get_factor_divisor --- src/class/cdc/cdc_host.c | 152 +++++++++++++++++++---------------- src/class/cdc/serial/ch34x.h | 6 ++ 2 files changed, 90 insertions(+), 68 deletions(-) diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 45a03a31d..150ac21f2 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -1179,7 +1179,7 @@ static void cp210x_process_config(tuh_xfer_t* xfer) { enum { CONFIG_CH34X_READ_VERSION = 0, - CONFIG_CH34X_SET_LINE_CODING, + CONFIG_CH34X_SERIAL_INIT, CONFIG_CH34X_SPECIAL_REG_WRITE, CONFIG_CH34X_FLOW_CONTROL, CONFIG_CH34X_MODEM_CONTROL, @@ -1231,7 +1231,9 @@ static bool ch34x_set_request(cdch_interface_t* p_cdc, uint8_t direction, uint8_ if (buffer && length > 0) { enum_buf = usbh_get_enum_buf(); - tu_memcpy_s(enum_buf, CFG_TUH_ENUMERATION_BUFSIZE, buffer, length); + if (direction == TUSB_DIR_OUT) { + tu_memcpy_s(enum_buf, CFG_TUH_ENUMERATION_BUFSIZE, buffer, length); + } } tuh_xfer_t xfer = { @@ -1257,8 +1259,8 @@ static inline bool ch34x_control_in(cdch_interface_t* p_cdc, uint8_t request, ui complete_cb, user_data); } -static bool ch34x_write_reg(cdch_interface_t* p_cdc, uint16_t reg, uint16_t value, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { - return ch34x_control_out(p_cdc, CH34X_REQ_WRITE_REG, reg, value, complete_cb, user_data); +static bool ch34x_write_reg(cdch_interface_t* p_cdc, uint16_t reg, uint16_t reg_value, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + return ch34x_control_out(p_cdc, CH34X_REQ_WRITE_REG, reg, reg_value, complete_cb, user_data); } //static bool ch34x_read_reg_request ( cdch_interface_t* p_cdc, uint16_t reg, @@ -1292,10 +1294,11 @@ static void ch34x_control_complete(tuh_xfer_t* xfer) { case CH34X_REQ_WRITE_REG: // register write request switch (value) { - case 0x1312: + case CH34X_REG16_DIVISOR_PRESCALER: // baudrate write p_cdc->line_coding.bit_rate = p_cdc->baudrate_requested; break; + default: TU_ASSERT(false,); // unexpected register write break; @@ -1309,6 +1312,7 @@ static void ch34x_control_complete(tuh_xfer_t* xfer) { } else { p_cdc->line_state &= (uint8_t ) ~CDC_CONTROL_LINE_STATE_RTS; } + if (~value & CH34X_BIT_DTR) { p_cdc->line_state |= CDC_CONTROL_LINE_STATE_DTR; } else { @@ -1377,8 +1381,8 @@ static void ch34x_control_complete(tuh_xfer_t* xfer) { } } -// calc baudrate factor and divisor -static bool ch34x_get_factor_divisor(uint32_t baval, uint8_t* factor, uint8_t* divisor) { +// calculate divisor and prescaler for baudrate, return it as 16-bit combined value +static uint16_t ch34x_get_divisor_prescaler(uint32_t baval) { uint8_t a; uint8_t b; uint32_t c; @@ -1410,7 +1414,7 @@ static bool ch34x_get_factor_divisor(uint32_t baval, uint8_t* factor, uint8_t* d } a = (unsigned char) (c / baval); if (a == 0 || a == 0xFF) { - return false; + return 0; } if ((c / a - baval) > (baval - c / (a + 1))) { a++; @@ -1418,74 +1422,75 @@ static bool ch34x_get_factor_divisor(uint32_t baval, uint8_t* factor, uint8_t* d a = (uint8_t) (256 - a); break; } - *factor = a; - *divisor = b; - return true; + // reg divisor = a, reg prescaler = b + // According to linux code we need to set bit 7 of UCHCOM_REG_BPS_PRE, + // otherwise the chip will buffer data. + return (uint16_t) (a << 8 | 0x80 | b); } -// calc lcr register value (data bits, parity, stop bits) -static bool ch34x_get_lcr(cdc_line_coding_t const* line_coding, uint8_t *lcr) { - *lcr = CH34X_LCR_ENABLE_RX | CH34X_LCR_ENABLE_TX; - switch (line_coding->data_bits) { - case 5: - *lcr |= CH34X_LCR_CS5; - break; - case 6: - *lcr |= CH34X_LCR_CS6; - break; - case 7: - *lcr |= CH34X_LCR_CS7; - break; - case 8: - *lcr |= CH34X_LCR_CS8; - break; - default: - TU_ASSERT (false); // data_bits not supported - break; +static inline uint8_t ch34x_get_lcr(uint8_t stop_bits, uint8_t parity, uint8_t data_bits) { + uint8_t lcr = CH34X_LCR_ENABLE_RX | CH34X_LCR_ENABLE_TX; + TU_VERIFY(data_bits >= 5, 0); + lcr |= (uint8_t) (data_bits - 5); + + if (parity) { + lcr |= CH34X_LCR_ENABLE_PAR; } - TU_ASSERT (line_coding->parity == CDC_LINE_CODING_PARITY_NONE || // supported parities - line_coding->parity == CDC_LINE_CODING_PARITY_ODD || line_coding->parity == CDC_LINE_CODING_PARITY_EVEN || - line_coding->parity == CDC_LINE_CODING_PARITY_MARK || line_coding->parity == CDC_LINE_CODING_PARITY_SPACE); - if (line_coding->parity != CDC_LINE_CODING_PARITY_NONE) { - *lcr |= CH34X_LCR_ENABLE_PAR; - if (line_coding->parity == CDC_LINE_CODING_PARITY_EVEN || line_coding->parity == CDC_LINE_CODING_PARITY_SPACE) { - *lcr |= CH34X_LCR_PAR_EVEN; - } - if (line_coding->parity == CDC_LINE_CODING_PARITY_MARK || line_coding->parity == CDC_LINE_CODING_PARITY_SPACE) { - *lcr |= CH34X_LCR_MARK_SPACE; - } + switch(parity) { + case CDC_LINE_CODING_PARITY_EVEN: + lcr |= CH34X_LCR_PAR_EVEN; + break; + + case CDC_LINE_CODING_PARITY_MARK: + lcr |= CH34X_LCR_MARK_SPACE; + break; + + case CDC_LINE_CODING_PARITY_SPACE: + lcr |= CH34X_LCR_MARK_SPACE | CH34X_LCR_PAR_EVEN; + break; + + default: break; } - TU_ASSERT (line_coding->stop_bits == CDC_LINE_CODING_STOP_BITS_1 || - line_coding->stop_bits == CDC_LINE_CODING_STOP_BITS_2); // not supported 1.5 stop bits - if (line_coding->stop_bits == CDC_LINE_CODING_STOP_BITS_2) { - *lcr |= CH34X_LCR_STOP_BITS_2; + + // 1.5 stop bits not supported + TU_VERIFY(stop_bits != CDC_LINE_CODING_STOP_BITS_1_5, 0); + if (stop_bits == CDC_LINE_CODING_STOP_BITS_2) { + lcr |= CH34X_LCR_STOP_BITS_2; } + return lcr; +} + +//static bool ch34x_set_line_data(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, +// tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + +static bool ch34x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + p_cdc->baudrate_requested = baudrate; + p_cdc->user_control_cb = complete_cb; + uint16_t const div_ps = ch34x_get_divisor_prescaler(baudrate); + TU_VERIFY(div_ps != 0); + TU_ASSERT(ch34x_write_reg(p_cdc, CH34X_REG16_DIVISOR_PRESCALER, div_ps, + complete_cb ? ch34x_control_complete : NULL, user_data)); + return true; } static bool ch34x_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { - p_cdc->baudrate_requested = line_coding->bit_rate; - p_cdc->user_control_cb = complete_cb; - uint8_t factor, divisor, lcr; - TU_ASSERT (ch34x_get_factor_divisor(line_coding->bit_rate, &factor, &divisor)); - TU_ASSERT (ch34x_get_lcr(line_coding, &lcr)); - TU_ASSERT (ch34x_control_out(p_cdc, CH34X_REQ_SERIAL_INIT, (uint16_t) (lcr << 8 | 0x9c), (uint16_t) (factor << 8 | 0x80 | divisor), - complete_cb ? ch34x_control_complete : NULL, user_data)); - return true; -} +// p_cdc->baudrate_requested = line_coding->bit_rate; +// p_cdc->user_control_cb = complete_cb; +// uint8_t factor, divisor, lcr; +// TU_ASSERT (ch34x_get_factor_divisor(line_coding->bit_rate, &factor, &divisor)); +// TU_ASSERT (ch34x_get_lcr(line_coding, &lcr)); +// TU_ASSERT (ch34x_control_out(p_cdc, CH34X_REQ_SERIAL_INIT, (uint16_t) (lcr << 8 | 0x9c), (uint16_t) (factor << 8 | 0x80 | divisor), +// complete_cb ? ch34x_control_complete : NULL, user_data)); + (void) p_cdc; + (void) line_coding; + (void) complete_cb; + (void) user_data; -static bool ch34x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) { - p_cdc->baudrate_requested = baudrate; - p_cdc->user_control_cb = complete_cb; - uint8_t factor, divisor; - TU_ASSERT (ch34x_get_factor_divisor(baudrate, &factor, &divisor)); - uint16_t const value = (uint16_t ) (factor << 8 | 0x80 | divisor); - TU_ASSERT (ch34x_write_reg(p_cdc, 0x1312, value, - complete_cb ? ch34x_control_complete : NULL, user_data)); return true; } @@ -1515,35 +1520,46 @@ static void ch34x_process_config(tuh_xfer_t* xfer) { switch (state) { case CONFIG_CH34X_READ_VERSION: - // version read request TU_LOG_DRV("[%u] CDCh CH34x attempt to read Chip Version\r\n", p_cdc->daddr); - TU_ASSERT (ch34x_control_in(p_cdc, CH34X_REQ_READ_VERSION, 0, 0, buffer, 2, ch34x_process_config, CONFIG_CH34X_SET_LINE_CODING),); + TU_ASSERT (ch34x_control_in(p_cdc, CH34X_REQ_READ_VERSION, 0, 0, buffer, 2, ch34x_process_config, CONFIG_CH34X_SERIAL_INIT),); break; - case CONFIG_CH34X_SET_LINE_CODING: + + case CONFIG_CH34X_SERIAL_INIT: { // handle version read data, set CH34x line coding (incl. baudrate) uint8_t version = xfer->buffer[0]; TU_LOG_DRV("[%u] CDCh CH34x Chip Version = %02x\r\n", p_cdc->daddr, version); // only versions >= 0x30 are tested, below 0x30 seems having other programming, see drivers from WCH vendor, Linux kernel and FreeBSD TU_ASSERT (version >= 0x30,); - TU_ASSERT (ch34x_set_line_coding(p_cdc, &line_coding, ch34x_process_config, CONFIG_CH34X_SPECIAL_REG_WRITE),); + uint16_t const div_ps = ch34x_get_divisor_prescaler(line_coding.bit_rate); + TU_ASSERT(div_ps != 0, ); + + uint8_t const lcr = ch34x_get_lcr(line_coding.stop_bits, line_coding.parity, line_coding.data_bits); + TU_ASSERT (ch34x_control_out(p_cdc, CH34X_REQ_SERIAL_INIT, tu_u16(lcr, 0x9c), div_ps, + ch34x_process_config, CONFIG_CH34X_SPECIAL_REG_WRITE),); break; + } + case CONFIG_CH34X_SPECIAL_REG_WRITE: // do special reg write, purpose unknown, overtaken from WCH driver TU_ASSERT (ch34x_write_reg(p_cdc, 0x0f2c, 0x0007, ch34x_process_config, CONFIG_CH34X_FLOW_CONTROL),); break; + case CONFIG_CH34X_FLOW_CONTROL: // no hardware flow control TU_ASSERT (ch34x_write_reg(p_cdc, 0x2727, 0x0000, ch34x_process_config, CONFIG_CH34X_MODEM_CONTROL),); break; + case CONFIG_CH34X_MODEM_CONTROL: // !always! set modem controls RTS/DTR (CH34x has no reset state after CH34X_REQ_SERIAL_INIT) TU_ASSERT (ch34x_set_modem_ctrl(p_cdc, CFG_TUH_CDC_LINE_CONTROL_ON_ENUM, ch34x_process_config, CONFIG_CH34X_COMPLETE),); break; + case CONFIG_CH34X_COMPLETE: set_config_complete(p_cdc, idx, itf_num); break; + default: - TU_ASSERT (false,); // something gone wrong, should never reached + TU_ASSERT (false,); break; } } diff --git a/src/class/cdc/serial/ch34x.h b/src/class/cdc/serial/ch34x.h index b4ed7420c..3f78a3007 100644 --- a/src/class/cdc/serial/ch34x.h +++ b/src/class/cdc/serial/ch34x.h @@ -59,6 +59,12 @@ #define CH34X_REG_MCR_MSR2 0x07 #define CH34X_NBREAK_BITS 0x01 +#define CH341_REG_0x0F 0x0F // undocumented register +#define CH341_REG_0x2C 0x2C // undocumented register +#define CH341_REG_0x27 0x27 // hardware flow control (cts/rts) + +#define CH34X_REG16_DIVISOR_PRESCALER TU_U16(CH34X_REG_DIVISOR, CH34X_REG_PRESCALER) + // modem control bits #define CH34X_BIT_RTS ( 1 << 6 ) #define CH34X_BIT_DTR ( 1 << 5 ) From c568a6793e99dde311802d4b4cb0633d2d6f5830 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 19 Jan 2024 12:14:45 +0700 Subject: [PATCH 058/454] - add requested line coding to make update data format easier - change ch34x_xfer_get_itf_num() to simply 0 --- src/class/cdc/cdc_host.c | 321 ++++++++++++++++++--------------------- 1 file changed, 149 insertions(+), 172 deletions(-) diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 150ac21f2..3843a8edc 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -60,6 +60,11 @@ typedef struct { uint8_t line_state; // DTR (bit0), RTS (bit1) TU_ATTR_ALIGNED(4) cdc_line_coding_t line_coding; // Baudrate, stop bits, parity, data width + #if CFG_TUH_CDC_FTDI || CFG_TUH_CDC_CP210X || CFG_TUH_CDC_CH34X + cdc_line_coding_t requested_line_coding; + // 1 byte padding + #endif + tuh_xfer_cb_t user_control_cb; struct { @@ -72,10 +77,6 @@ typedef struct { uint8_t rx_ff_buf[CFG_TUH_CDC_TX_BUFSIZE]; CFG_TUH_MEM_ALIGN uint8_t rx_ep_buf[CFG_TUH_CDC_TX_EPSIZE]; } stream; - -#if CFG_TUH_CDC_FTDI || CFG_TUH_CDC_CH34X - uint32_t baudrate_requested; -#endif } cdch_interface_t; CFG_TUH_MEM_SECTION @@ -429,7 +430,7 @@ static void cdch_internal_control_complete(tuh_xfer_t* xfer) { case FTDI_SIO_SET_BAUD_RATE: // convert from divisor to baudrate is not supported - p_cdc->line_coding.bit_rate = p_cdc->baudrate_requested; + p_cdc->line_coding.bit_rate = p_cdc->requested_line_coding.bit_rate; break; default: break; @@ -968,7 +969,7 @@ static bool ftdi_sio_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tu TU_LOG_DRV("CDC FTDI Set BaudRate = %lu, divisor = 0x%04x\r\n", baudrate, divisor); p_cdc->user_control_cb = complete_cb; - p_cdc->baudrate_requested = baudrate; + p_cdc->requested_line_coding.bit_rate = baudrate; TU_ASSERT(ftdi_sio_set_request(p_cdc, FTDI_SIO_SET_BAUD_RATE, divisor, complete_cb ? cdch_internal_control_complete : NULL, user_data)); @@ -1186,6 +1187,9 @@ enum { CONFIG_CH34X_COMPLETE }; +static uint8_t ch34x_get_lcr(uint8_t stop_bits, uint8_t parity, uint8_t data_bits); +static uint16_t ch34x_get_divisor_prescaler(uint32_t baval); + static bool ch34x_open(uint8_t daddr, tusb_desc_interface_t const* itf_desc, uint16_t max_len) { // CH34x Interface includes 1 vendor interface + 2 bulk + 1 interrupt endpoints TU_VERIFY (itf_desc->bNumEndpoints == 3); @@ -1269,20 +1273,10 @@ static bool ch34x_write_reg(cdch_interface_t* p_cdc, uint16_t reg, uint16_t reg_ // return ch34x_control_in ( p_cdc, CH34X_REQ_READ_REG, reg, 0, buffer, buffersize, complete_cb, user_data ); //} -uint8_t ch34x_xfer_get_itf_num(tuh_xfer_t* xfer) { -// CH34x needs a special handling to get bInterfaceNumber, because wIndex is used for other purposes and not for bInterfaceNumber -// CH340 and CH341 derivates have always only one interface, so it's OK to check only daddr - for (uint8_t i = 0; i < CFG_TUH_CDC; i++) { - const cdch_interface_t* p_cdc = &cdch_data[i]; - if (p_cdc->daddr == xfer->daddr) return p_cdc->bInterfaceNumber; - } - - return INTERFACE_INVALID_NUMBER; -} - // internal control complete to update state such as line state, encoding static void ch34x_control_complete(tuh_xfer_t* xfer) { - uint8_t const itf_num = ch34x_xfer_get_itf_num(xfer); + // CH34x only has 1 interface and use wIndex as payload and not for bInterfaceNumber + uint8_t const itf_num = 0; uint8_t const idx = tuh_cdc_itf_get_index(xfer->daddr, itf_num); cdch_interface_t* p_cdc = get_itf(idx); uint16_t value = tu_le16toh (xfer->setup->wValue); @@ -1296,7 +1290,14 @@ static void ch34x_control_complete(tuh_xfer_t* xfer) { switch (value) { case CH34X_REG16_DIVISOR_PRESCALER: // baudrate write - p_cdc->line_coding.bit_rate = p_cdc->baudrate_requested; + p_cdc->line_coding.bit_rate = p_cdc->requested_line_coding.bit_rate; + break; + + case CH32X_REG16_LCR2_LCR: + // data format write + p_cdc->line_coding.stop_bits = p_cdc->requested_line_coding.stop_bits; + p_cdc->line_coding.parity = p_cdc->requested_line_coding.parity; + p_cdc->line_coding.data_bits = p_cdc->requested_line_coding.data_bits; break; default: @@ -1305,68 +1306,26 @@ static void ch34x_control_complete(tuh_xfer_t* xfer) { } break; - case CH34X_REQ_MODEM_CTRL: - // set modem controls RTS/DTR request - if (~value & CH34X_BIT_RTS) { + case CH34X_REQ_MODEM_CTRL: { + // set modem controls RTS/DTR request. Note: signals are inverted + uint16_t const modem_signal = ~value; + if (modem_signal & CH34X_BIT_RTS) { p_cdc->line_state |= CDC_CONTROL_LINE_STATE_RTS; } else { - p_cdc->line_state &= (uint8_t ) ~CDC_CONTROL_LINE_STATE_RTS; + p_cdc->line_state &= (uint8_t) ~CDC_CONTROL_LINE_STATE_RTS; } - if (~value & CH34X_BIT_DTR) { + if (modem_signal & CH34X_BIT_DTR) { p_cdc->line_state |= CDC_CONTROL_LINE_STATE_DTR; } else { - p_cdc->line_state &= (uint8_t ) ~CDC_CONTROL_LINE_STATE_DTR; + p_cdc->line_state &= (uint8_t) ~CDC_CONTROL_LINE_STATE_DTR; } break; + } case CH34X_REQ_SERIAL_INIT: // serial init request (set line coding incl. baudrate) - p_cdc->line_coding.bit_rate = p_cdc->baudrate_requested; - uint8_t lcr = (uint8_t) (value >> 8); - TU_ASSERT (lcr & CH34X_LCR_ENABLE_RX && lcr & CH34X_LCR_ENABLE_TX,); // both have to be enabled - switch (lcr & CH34X_LCR_CS_MASK) { - case CH34X_LCR_CS5: - p_cdc->line_coding.data_bits = 5; - break; - case CH34X_LCR_CS6: - p_cdc->line_coding.data_bits = 6; - break; - case CH34X_LCR_CS7: - p_cdc->line_coding.data_bits = 7; - break; - case CH34X_LCR_CS8: - p_cdc->line_coding.data_bits = 8; - break; - default: - TU_ASSERT (false,); // unexpected data_bits lcr - break; - } - if (lcr & CH34X_LCR_STOP_BITS_2) { - p_cdc->line_coding.stop_bits = CDC_LINE_CODING_STOP_BITS_2; - } else { - p_cdc->line_coding.stop_bits = CDC_LINE_CODING_STOP_BITS_1; - } - switch (lcr & CH34X_LCR_PAR_MASK) { - case 0: - p_cdc->line_coding.parity = CDC_LINE_CODING_PARITY_NONE; - break; - case CH34X_LCR_ENABLE_PAR: - p_cdc->line_coding.parity = CDC_LINE_CODING_PARITY_ODD; - break; - case CH34X_LCR_ENABLE_PAR | CH34X_LCR_PAR_EVEN: - p_cdc->line_coding.parity = CDC_LINE_CODING_PARITY_EVEN; - break; - case CH34X_LCR_ENABLE_PAR | CH34X_LCR_MARK_SPACE: - p_cdc->line_coding.parity = CDC_LINE_CODING_PARITY_MARK; - break; - case CH34X_LCR_ENABLE_PAR | CH34X_LCR_MARK_SPACE | CH34X_LCR_PAR_EVEN: - p_cdc->line_coding.parity = CDC_LINE_CODING_PARITY_SPACE; - break; - default: - TU_ASSERT (false,); // unexpected parity lcr - break; - } + p_cdc->line_coding = p_cdc->requested_line_coding; break; default: @@ -1381,6 +1340,124 @@ static void ch34x_control_complete(tuh_xfer_t* xfer) { } } +//static bool ch34x_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, +// tuh_xfer_cb_t complete_cb, uintptr_t user_data) { +// uint8_t const lcr = ch34x_get_lcr(stop_bits, parity, data_bits); +// TU_ASSERT (ch34x_control_out(p_cdc, CH34X_REQ_WRITE_REG, CH32X_REG16_LCR2_LCR, lcr, +// complete_cb ? ch34x_control_complete : NULL, user_data)); +// return false; +//} + +static bool ch34x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + p_cdc->requested_line_coding.bit_rate = baudrate; + p_cdc->user_control_cb = complete_cb; + uint16_t const div_ps = ch34x_get_divisor_prescaler(baudrate); + TU_VERIFY(div_ps != 0); + TU_ASSERT(ch34x_write_reg(p_cdc, CH34X_REG16_DIVISOR_PRESCALER, div_ps, + complete_cb ? ch34x_control_complete : NULL, user_data)); + + return true; +} + +static bool ch34x_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { +// p_cdc->baudrate_requested = line_coding->bit_rate; +// p_cdc->user_control_cb = complete_cb; +// uint8_t factor, divisor, lcr; +// TU_ASSERT (ch34x_get_factor_divisor(line_coding->bit_rate, &factor, &divisor)); +// TU_ASSERT (ch34x_get_lcr(line_coding, &lcr)); +// TU_ASSERT (ch34x_control_out(p_cdc, CH34X_REQ_SERIAL_INIT, (uint16_t) (lcr << 8 | 0x9c), (uint16_t) (factor << 8 | 0x80 | divisor), +// complete_cb ? ch34x_control_complete : NULL, user_data)); + (void) p_cdc; + (void) line_coding; + (void) complete_cb; + (void) user_data; + + return true; +} + +static bool ch34x_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + uint8_t control = 0; + if (line_state & CDC_CONTROL_LINE_STATE_RTS) { + control |= CH34X_BIT_RTS; + } + if (line_state & CDC_CONTROL_LINE_STATE_DTR) { + control |= CH34X_BIT_DTR; + } + + // CH34x signals are inverted + control = ~control; + + p_cdc->user_control_cb = complete_cb; + TU_ASSERT (ch34x_control_out(p_cdc, CH34X_REQ_MODEM_CTRL, control, 0, + complete_cb ? ch34x_control_complete : NULL, user_data)); + return true; +} + +static void ch34x_process_config(tuh_xfer_t* xfer) { + // CH34x only has 1 interface and use wIndex as payload and not for bInterfaceNumber + uint8_t const itf_num = 0; + uint8_t const idx = tuh_cdc_itf_get_index(xfer->daddr, itf_num); + cdch_interface_t* p_cdc = get_itf(idx); + uintptr_t const state = xfer->user_data; + cdc_line_coding_t const line_coding = CFG_TUH_CDC_LINE_CODING_ON_ENUM_CH34X; + uint8_t buffer[2]; // TODO remove + TU_ASSERT (p_cdc,); + + switch (state) { + case CONFIG_CH34X_READ_VERSION: + TU_LOG_DRV("[%u] CDCh CH34x attempt to read Chip Version\r\n", p_cdc->daddr); + TU_ASSERT (ch34x_control_in(p_cdc, CH34X_REQ_READ_VERSION, 0, 0, buffer, 2, ch34x_process_config, CONFIG_CH34X_SERIAL_INIT),); + break; + + case CONFIG_CH34X_SERIAL_INIT: { + // handle version read data, set CH34x line coding (incl. baudrate) + uint8_t const version = xfer->buffer[0]; + TU_LOG_DRV("[%u] CDCh CH34x Chip Version = %02x\r\n", p_cdc->daddr, version); + // only versions >= 0x30 are tested, below 0x30 seems having other programming, see drivers from WCH vendor, Linux kernel and FreeBSD + TU_ASSERT (version >= 0x30,); + + uint16_t const div_ps = ch34x_get_divisor_prescaler(line_coding.bit_rate); + TU_ASSERT(div_ps != 0, ); + + uint8_t const lcr = ch34x_get_lcr(line_coding.stop_bits, line_coding.parity, line_coding.data_bits); + + // Init CH34x with line coding + TU_ASSERT (ch34x_control_out(p_cdc, CH34X_REQ_SERIAL_INIT, tu_u16(lcr, 0x9c), div_ps, + ch34x_process_config, CONFIG_CH34X_SPECIAL_REG_WRITE),); + break; + } + + case CONFIG_CH34X_SPECIAL_REG_WRITE: + // do special reg write, purpose unknown, overtaken from WCH driver + p_cdc->line_coding = line_coding; + TU_ASSERT (ch34x_write_reg(p_cdc, 0x0f2c, 0x0007, ch34x_process_config, CONFIG_CH34X_FLOW_CONTROL),); + break; + + case CONFIG_CH34X_FLOW_CONTROL: + // no hardware flow control + TU_ASSERT (ch34x_write_reg(p_cdc, 0x2727, 0x0000, ch34x_process_config, CONFIG_CH34X_MODEM_CONTROL),); + break; + + case CONFIG_CH34X_MODEM_CONTROL: + // !always! set modem controls RTS/DTR (CH34x has no reset state after CH34X_REQ_SERIAL_INIT) + TU_ASSERT (ch34x_set_modem_ctrl(p_cdc, CFG_TUH_CDC_LINE_CONTROL_ON_ENUM, ch34x_process_config, CONFIG_CH34X_COMPLETE),); + break; + + case CONFIG_CH34X_COMPLETE: + set_config_complete(p_cdc, idx, itf_num); + break; + + default: + TU_ASSERT (false,); + break; + } +} + +//------------- CH34x helper -------------// + // calculate divisor and prescaler for baudrate, return it as 16-bit combined value static uint16_t ch34x_get_divisor_prescaler(uint32_t baval) { uint8_t a; @@ -1429,7 +1506,8 @@ static uint16_t ch34x_get_divisor_prescaler(uint32_t baval) { return (uint16_t) (a << 8 | 0x80 | b); } -static inline uint8_t ch34x_get_lcr(uint8_t stop_bits, uint8_t parity, uint8_t data_bits) { +// calculate lcr value from data coding +static uint8_t ch34x_get_lcr(uint8_t stop_bits, uint8_t parity, uint8_t data_bits) { uint8_t lcr = CH34X_LCR_ENABLE_RX | CH34X_LCR_ENABLE_TX; TU_VERIFY(data_bits >= 5, 0); lcr |= (uint8_t) (data_bits - 5); @@ -1462,107 +1540,6 @@ static inline uint8_t ch34x_get_lcr(uint8_t stop_bits, uint8_t parity, uint8_t d return lcr; } -//static bool ch34x_set_line_data(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, -// tuh_xfer_cb_t complete_cb, uintptr_t user_data) { - -static bool ch34x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) { - p_cdc->baudrate_requested = baudrate; - p_cdc->user_control_cb = complete_cb; - uint16_t const div_ps = ch34x_get_divisor_prescaler(baudrate); - TU_VERIFY(div_ps != 0); - TU_ASSERT(ch34x_write_reg(p_cdc, CH34X_REG16_DIVISOR_PRESCALER, div_ps, - complete_cb ? ch34x_control_complete : NULL, user_data)); - - return true; -} - -static bool ch34x_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) { -// p_cdc->baudrate_requested = line_coding->bit_rate; -// p_cdc->user_control_cb = complete_cb; -// uint8_t factor, divisor, lcr; -// TU_ASSERT (ch34x_get_factor_divisor(line_coding->bit_rate, &factor, &divisor)); -// TU_ASSERT (ch34x_get_lcr(line_coding, &lcr)); -// TU_ASSERT (ch34x_control_out(p_cdc, CH34X_REQ_SERIAL_INIT, (uint16_t) (lcr << 8 | 0x9c), (uint16_t) (factor << 8 | 0x80 | divisor), -// complete_cb ? ch34x_control_complete : NULL, user_data)); - (void) p_cdc; - (void) line_coding; - (void) complete_cb; - (void) user_data; - - return true; -} - -static bool ch34x_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) { - p_cdc->user_control_cb = complete_cb; - uint16_t control = 0; - if (line_state & CDC_CONTROL_LINE_STATE_RTS) { - control |= CH34X_BIT_RTS; - } - if (line_state & CDC_CONTROL_LINE_STATE_DTR) { - control |= CH34X_BIT_DTR; - } - TU_ASSERT (ch34x_control_out(p_cdc, CH34X_REQ_MODEM_CTRL, (uint8_t) ~control, 0, - complete_cb ? ch34x_control_complete : NULL, user_data)); - return true; -} - -static void ch34x_process_config(tuh_xfer_t* xfer) { - uint8_t const itf_num = ch34x_xfer_get_itf_num(xfer); - uintptr_t const state = xfer->user_data; - uint8_t const idx = tuh_cdc_itf_get_index(xfer->daddr, itf_num); - cdch_interface_t* p_cdc = get_itf(idx); - cdc_line_coding_t const line_coding = CFG_TUH_CDC_LINE_CODING_ON_ENUM_CH34X; - uint8_t buffer[2]; // TODO remove - TU_ASSERT (p_cdc,); - - switch (state) { - case CONFIG_CH34X_READ_VERSION: - TU_LOG_DRV("[%u] CDCh CH34x attempt to read Chip Version\r\n", p_cdc->daddr); - TU_ASSERT (ch34x_control_in(p_cdc, CH34X_REQ_READ_VERSION, 0, 0, buffer, 2, ch34x_process_config, CONFIG_CH34X_SERIAL_INIT),); - break; - - case CONFIG_CH34X_SERIAL_INIT: { - // handle version read data, set CH34x line coding (incl. baudrate) - uint8_t version = xfer->buffer[0]; - TU_LOG_DRV("[%u] CDCh CH34x Chip Version = %02x\r\n", p_cdc->daddr, version); - // only versions >= 0x30 are tested, below 0x30 seems having other programming, see drivers from WCH vendor, Linux kernel and FreeBSD - TU_ASSERT (version >= 0x30,); - uint16_t const div_ps = ch34x_get_divisor_prescaler(line_coding.bit_rate); - TU_ASSERT(div_ps != 0, ); - - uint8_t const lcr = ch34x_get_lcr(line_coding.stop_bits, line_coding.parity, line_coding.data_bits); - TU_ASSERT (ch34x_control_out(p_cdc, CH34X_REQ_SERIAL_INIT, tu_u16(lcr, 0x9c), div_ps, - ch34x_process_config, CONFIG_CH34X_SPECIAL_REG_WRITE),); - break; - } - - case CONFIG_CH34X_SPECIAL_REG_WRITE: - // do special reg write, purpose unknown, overtaken from WCH driver - TU_ASSERT (ch34x_write_reg(p_cdc, 0x0f2c, 0x0007, ch34x_process_config, CONFIG_CH34X_FLOW_CONTROL),); - break; - - case CONFIG_CH34X_FLOW_CONTROL: - // no hardware flow control - TU_ASSERT (ch34x_write_reg(p_cdc, 0x2727, 0x0000, ch34x_process_config, CONFIG_CH34X_MODEM_CONTROL),); - break; - - case CONFIG_CH34X_MODEM_CONTROL: - // !always! set modem controls RTS/DTR (CH34x has no reset state after CH34X_REQ_SERIAL_INIT) - TU_ASSERT (ch34x_set_modem_ctrl(p_cdc, CFG_TUH_CDC_LINE_CONTROL_ON_ENUM, ch34x_process_config, CONFIG_CH34X_COMPLETE),); - break; - - case CONFIG_CH34X_COMPLETE: - set_config_complete(p_cdc, idx, itf_num); - break; - - default: - TU_ASSERT (false,); - break; - } -} #endif // CFG_TUH_CDC_CH34X From 23c2d929a1bae39578b195c7c7b068fb718212bd Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 19 Jan 2024 12:40:37 +0700 Subject: [PATCH 059/454] refactor process_internal_control_complete() --- src/class/cdc/cdc_host.c | 142 +++++++++++++++++++-------------------- 1 file changed, 69 insertions(+), 73 deletions(-) diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 3843a8edc..bfaa64a77 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -396,26 +396,23 @@ bool tuh_cdc_read_clear (uint8_t idx) { // Control Endpoint API //--------------------------------------------------------------------+ -// internal control complete to update state such as line state, encoding -static void cdch_internal_control_complete(tuh_xfer_t* xfer) { - uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); - uint8_t idx = tuh_cdc_itf_get_index(xfer->daddr, itf_num); - cdch_interface_t* p_cdc = get_itf(idx); +static void process_internal_control_complete(cdch_interface_t* p_cdc, tuh_xfer_t* xfer) { TU_ASSERT(p_cdc, ); + uint16_t const value = tu_le16toh(xfer->setup->wValue); if (xfer->result == XFER_RESULT_SUCCESS) { switch (p_cdc->serial_drid) { case SERIAL_DRIVER_ACM: switch (xfer->setup->bRequest) { case CDC_REQUEST_SET_CONTROL_LINE_STATE: - p_cdc->line_state = (uint8_t) tu_le16toh(xfer->setup->wValue); + p_cdc->line_state = (uint8_t) value; break; case CDC_REQUEST_SET_LINE_CODING: { uint16_t const len = tu_min16(sizeof(cdc_line_coding_t), tu_le16toh(xfer->setup->wLength)); memcpy(&p_cdc->line_coding, xfer->buffer, len); - } break; + } default: break; } @@ -425,11 +422,10 @@ static void cdch_internal_control_complete(tuh_xfer_t* xfer) { case SERIAL_DRIVER_FTDI: switch (xfer->setup->bRequest) { case FTDI_SIO_MODEM_CTRL: - p_cdc->line_state = (uint8_t) (tu_le16toh(xfer->setup->wValue) & 0x00ff); + p_cdc->line_state = (uint8_t) value; break; case FTDI_SIO_SET_BAUD_RATE: - // convert from divisor to baudrate is not supported p_cdc->line_coding.bit_rate = p_cdc->requested_line_coding.bit_rate; break; @@ -442,22 +438,62 @@ static void cdch_internal_control_complete(tuh_xfer_t* xfer) { case SERIAL_DRIVER_CP210X: switch(xfer->setup->bRequest) { case CP210X_SET_MHS: - p_cdc->line_state = (uint8_t) (tu_le16toh(xfer->setup->wValue) & 0x00ff); + p_cdc->line_state = (uint8_t) value; break; case CP210X_SET_BAUDRATE: { uint32_t baudrate; memcpy(&baudrate, xfer->buffer, sizeof(uint32_t)); p_cdc->line_coding.bit_rate = tu_le32toh(baudrate); - } break; + } + + default: break; } break; #endif #if CFG_TUH_CDC_CH34X case SERIAL_DRIVER_CH34X: - TU_ASSERT(false, ); // see special ch34x_control_complete function + switch (xfer->setup->bRequest) { + case CH34X_REQ_WRITE_REG: + // register write request + switch (value) { + case CH34X_REG16_DIVISOR_PRESCALER: + // baudrate + p_cdc->line_coding.bit_rate = p_cdc->requested_line_coding.bit_rate; + break; + + case CH32X_REG16_LCR2_LCR: + // data format + p_cdc->line_coding.stop_bits = p_cdc->requested_line_coding.stop_bits; + p_cdc->line_coding.parity = p_cdc->requested_line_coding.parity; + p_cdc->line_coding.data_bits = p_cdc->requested_line_coding.data_bits; + break; + + default: break; + } + break; + + case CH34X_REQ_MODEM_CTRL: { + // set modem controls RTS/DTR request. Note: signals are inverted + uint16_t const modem_signal = ~value; + if (modem_signal & CH34X_BIT_RTS) { + p_cdc->line_state |= CDC_CONTROL_LINE_STATE_RTS; + } else { + p_cdc->line_state &= (uint8_t) ~CDC_CONTROL_LINE_STATE_RTS; + } + + if (modem_signal & CH34X_BIT_DTR) { + p_cdc->line_state |= CDC_CONTROL_LINE_STATE_DTR; + } else { + p_cdc->line_state &= (uint8_t) ~CDC_CONTROL_LINE_STATE_DTR; + } + break; + } + + default: break; + } break; #endif @@ -471,6 +507,15 @@ static void cdch_internal_control_complete(tuh_xfer_t* xfer) { } } +// internal control complete to update state such as line state, encoding +static void cdch_internal_control_complete(tuh_xfer_t* xfer) { + uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); + uint8_t idx = tuh_cdc_itf_get_index(xfer->daddr, itf_num); + cdch_interface_t* p_cdc = get_itf(idx); + + process_internal_control_complete(p_cdc, xfer); +} + bool tuh_cdc_set_control_line_state(uint8_t idx, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc && p_cdc->serial_drid < SERIAL_DRIVER_COUNT); @@ -1279,70 +1324,16 @@ static void ch34x_control_complete(tuh_xfer_t* xfer) { uint8_t const itf_num = 0; uint8_t const idx = tuh_cdc_itf_get_index(xfer->daddr, itf_num); cdch_interface_t* p_cdc = get_itf(idx); - uint16_t value = tu_le16toh (xfer->setup->wValue); - TU_ASSERT (p_cdc,); - TU_ASSERT (p_cdc->serial_drid == SERIAL_DRIVER_CH34X,); - - if (xfer->result == XFER_RESULT_SUCCESS) { - switch (xfer->setup->bRequest) { - case CH34X_REQ_WRITE_REG: - // register write request - switch (value) { - case CH34X_REG16_DIVISOR_PRESCALER: - // baudrate write - p_cdc->line_coding.bit_rate = p_cdc->requested_line_coding.bit_rate; - break; - - case CH32X_REG16_LCR2_LCR: - // data format write - p_cdc->line_coding.stop_bits = p_cdc->requested_line_coding.stop_bits; - p_cdc->line_coding.parity = p_cdc->requested_line_coding.parity; - p_cdc->line_coding.data_bits = p_cdc->requested_line_coding.data_bits; - break; - - default: - TU_ASSERT(false,); // unexpected register write - break; - } - break; - - case CH34X_REQ_MODEM_CTRL: { - // set modem controls RTS/DTR request. Note: signals are inverted - uint16_t const modem_signal = ~value; - if (modem_signal & CH34X_BIT_RTS) { - p_cdc->line_state |= CDC_CONTROL_LINE_STATE_RTS; - } else { - p_cdc->line_state &= (uint8_t) ~CDC_CONTROL_LINE_STATE_RTS; - } - - if (modem_signal & CH34X_BIT_DTR) { - p_cdc->line_state |= CDC_CONTROL_LINE_STATE_DTR; - } else { - p_cdc->line_state &= (uint8_t) ~CDC_CONTROL_LINE_STATE_DTR; - } - break; - } - - case CH34X_REQ_SERIAL_INIT: - // serial init request (set line coding incl. baudrate) - p_cdc->line_coding = p_cdc->requested_line_coding; - break; - - default: - TU_ASSERT(false,); // unexpected request - break; - } - - xfer->complete_cb = p_cdc->user_control_cb; - if (xfer->complete_cb) { - xfer->complete_cb(xfer); - } - } + process_internal_control_complete(p_cdc, xfer); } //static bool ch34x_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, // tuh_xfer_cb_t complete_cb, uintptr_t user_data) { // uint8_t const lcr = ch34x_get_lcr(stop_bits, parity, data_bits); +// p_cdc->requested_line_coding.stop_bits = stop_bits; +// p_cdc->requested_line_coding.parity = parity; +// p_cdc->requested_line_coding.data_bits = data_bits; +// // TU_ASSERT (ch34x_control_out(p_cdc, CH34X_REQ_WRITE_REG, CH32X_REG16_LCR2_LCR, lcr, // complete_cb ? ch34x_control_complete : NULL, user_data)); // return false; @@ -1350,16 +1341,21 @@ static void ch34x_control_complete(tuh_xfer_t* xfer) { static bool ch34x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { - p_cdc->requested_line_coding.bit_rate = baudrate; - p_cdc->user_control_cb = complete_cb; uint16_t const div_ps = ch34x_get_divisor_prescaler(baudrate); TU_VERIFY(div_ps != 0); + + p_cdc->requested_line_coding.bit_rate = baudrate; + p_cdc->user_control_cb = complete_cb; TU_ASSERT(ch34x_write_reg(p_cdc, CH34X_REG16_DIVISOR_PRESCALER, div_ps, complete_cb ? ch34x_control_complete : NULL, user_data)); return true; } +//static void ch34x_set_line_coding_stage1(tuh_xfer_t* xfer) { +// +//} + static bool ch34x_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { // p_cdc->baudrate_requested = line_coding->bit_rate; From 98781bb903d94190d57ad4b9436a85a31d67404c Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 19 Jan 2024 15:58:05 +0700 Subject: [PATCH 060/454] - add ch34x_set_data_format() - add ch34x_set_line_coding() --- examples/host/cdc_msc_hid/src/cdc_app.c | 68 +++++++-------- src/class/cdc/cdc_host.c | 110 ++++++++++++++++-------- src/class/cdc/serial/ch34x.h | 3 +- 3 files changed, 107 insertions(+), 74 deletions(-) diff --git a/examples/host/cdc_msc_hid/src/cdc_app.c b/examples/host/cdc_msc_hid/src/cdc_app.c index a1b26e49c..81052047c 100644 --- a/examples/host/cdc_msc_hid/src/cdc_app.c +++ b/examples/host/cdc_msc_hid/src/cdc_app.c @@ -27,20 +27,11 @@ #include "tusb.h" #include "bsp/board_api.h" -//--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM DECLARATION -//--------------------------------------------------------------------+ - - -//------------- IMPLEMENTATION -------------// - -size_t get_console_inputs(uint8_t* buf, size_t bufsize) -{ +size_t get_console_inputs(uint8_t* buf, size_t bufsize) { size_t count = 0; - while (count < bufsize) - { + while (count < bufsize) { int ch = board_getchar(); - if ( ch <= 0 ) break; + if (ch <= 0) break; buf[count] = (uint8_t) ch; count++; @@ -49,22 +40,18 @@ size_t get_console_inputs(uint8_t* buf, size_t bufsize) return count; } -void cdc_app_task(void) -{ - uint8_t buf[64+1]; // +1 for extra null character - uint32_t const bufsize = sizeof(buf)-1; +void cdc_app_task(void) { + uint8_t buf[64 + 1]; // +1 for extra null character + uint32_t const bufsize = sizeof(buf) - 1; uint32_t count = get_console_inputs(buf, bufsize); buf[count] = 0; // loop over all mounted interfaces - for(uint8_t idx=0; idx cdc interfaces - if (count) - { + if (count) { tuh_cdc_write(idx, buf, count); tuh_cdc_write_flush(idx); } @@ -72,11 +59,14 @@ void cdc_app_task(void) } } +//--------------------------------------------------------------------+ +// TinyUSB callbacks +//--------------------------------------------------------------------+ + // Invoked when received new data -void tuh_cdc_rx_cb(uint8_t idx) -{ - uint8_t buf[64+1]; // +1 for extra null character - uint32_t const bufsize = sizeof(buf)-1; +void tuh_cdc_rx_cb(uint8_t idx) { + uint8_t buf[64 + 1]; // +1 for extra null character + uint32_t const bufsize = sizeof(buf) - 1; // forward cdc interfaces -> console uint32_t count = tuh_cdc_read(idx, buf, bufsize); @@ -85,29 +75,31 @@ void tuh_cdc_rx_cb(uint8_t idx) printf((char*) buf); } -void tuh_cdc_mount_cb(uint8_t idx) -{ - tuh_itf_info_t itf_info = { 0 }; +// Invoked when a device with CDC interface is mounted +// idx is index of cdc interface in the internal pool. +void tuh_cdc_mount_cb(uint8_t idx) { + tuh_itf_info_t itf_info = {0}; tuh_cdc_itf_get_info(idx, &itf_info); - printf("CDC Interface is mounted: address = %u, itf_num = %u\r\n", itf_info.daddr, itf_info.desc.bInterfaceNumber); + printf("CDC Interface is mounted: address = %u, itf_num = %u\r\n", itf_info.daddr, + itf_info.desc.bInterfaceNumber); #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM // CFG_TUH_CDC_LINE_CODING_ON_ENUM must be defined for line coding is set by tinyusb in enumeration // otherwise you need to call tuh_cdc_set_line_coding() first - cdc_line_coding_t line_coding = { 0 }; - if ( tuh_cdc_get_local_line_coding(idx, &line_coding) ) - { + cdc_line_coding_t line_coding = {0}; + if (tuh_cdc_get_local_line_coding(idx, &line_coding)) { printf(" Baudrate: %lu, Stop Bits : %u\r\n", line_coding.bit_rate, line_coding.stop_bits); - printf(" Parity : %u, Data Width: %u\r\n", line_coding.parity , line_coding.data_bits); + printf(" Parity : %u, Data Width: %u\r\n", line_coding.parity, line_coding.data_bits); } #endif } -void tuh_cdc_umount_cb(uint8_t idx) -{ - tuh_itf_info_t itf_info = { 0 }; +// Invoked when a device with CDC interface is unmounted +void tuh_cdc_umount_cb(uint8_t idx) { + tuh_itf_info_t itf_info = {0}; tuh_cdc_itf_get_info(idx, &itf_info); - printf("CDC Interface is unmounted: address = %u, itf_num = %u\r\n", itf_info.daddr, itf_info.desc.bInterfaceNumber); + printf("CDC Interface is unmounted: address = %u, itf_num = %u\r\n", itf_info.daddr, + itf_info.desc.bInterfaceNumber); } diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index bfaa64a77..37fa30982 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -1327,48 +1327,88 @@ static void ch34x_control_complete(tuh_xfer_t* xfer) { process_internal_control_complete(p_cdc, xfer); } -//static bool ch34x_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, -// tuh_xfer_cb_t complete_cb, uintptr_t user_data) { -// uint8_t const lcr = ch34x_get_lcr(stop_bits, parity, data_bits); -// p_cdc->requested_line_coding.stop_bits = stop_bits; -// p_cdc->requested_line_coding.parity = parity; -// p_cdc->requested_line_coding.data_bits = data_bits; -// -// TU_ASSERT (ch34x_control_out(p_cdc, CH34X_REQ_WRITE_REG, CH32X_REG16_LCR2_LCR, lcr, -// complete_cb ? ch34x_control_complete : NULL, user_data)); -// return false; -//} - -static bool ch34x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) { - uint16_t const div_ps = ch34x_get_divisor_prescaler(baudrate); - TU_VERIFY(div_ps != 0); - - p_cdc->requested_line_coding.bit_rate = baudrate; - p_cdc->user_control_cb = complete_cb; - TU_ASSERT(ch34x_write_reg(p_cdc, CH34X_REG16_DIVISOR_PRESCALER, div_ps, - complete_cb ? ch34x_control_complete : NULL, user_data)); +static bool ch34x_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + p_cdc->requested_line_coding.stop_bits = stop_bits; + p_cdc->requested_line_coding.parity = parity; + p_cdc->requested_line_coding.data_bits = data_bits; + uint8_t const lcr = ch34x_get_lcr(stop_bits, parity, data_bits); + TU_ASSERT (ch34x_control_out(p_cdc, CH34X_REQ_WRITE_REG, CH32X_REG16_LCR2_LCR, lcr, + complete_cb ? ch34x_control_complete : NULL, user_data)); return true; } -//static void ch34x_set_line_coding_stage1(tuh_xfer_t* xfer) { -// -//} +static bool ch34x_write_reg_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + uint16_t const div_ps = ch34x_get_divisor_prescaler(baudrate); + TU_VERIFY(div_ps != 0); + TU_ASSERT(ch34x_write_reg(p_cdc, CH34X_REG16_DIVISOR_PRESCALER, div_ps, + complete_cb, user_data)); + return true; +} +static bool ch34x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + p_cdc->requested_line_coding.bit_rate = baudrate; + p_cdc->user_control_cb = complete_cb; + TU_ASSERT(ch34x_write_reg_baudrate(p_cdc, baudrate, + complete_cb ? ch34x_control_complete : NULL, user_data)); + return true; +} + +static void ch34x_set_line_coding_stage1_complete(tuh_xfer_t* xfer) { + uint8_t const itf_num = 0; + uint8_t const idx = tuh_cdc_itf_get_index(xfer->daddr, itf_num); + cdch_interface_t* p_cdc = get_itf(idx); + TU_ASSERT(p_cdc, ); + + if (xfer->result == XFER_RESULT_SUCCESS) { + // stage 1 success, continue to stage 2 + p_cdc->line_coding.bit_rate = p_cdc->requested_line_coding.bit_rate; + TU_ASSERT(ch34x_set_data_format(p_cdc, p_cdc->requested_line_coding.stop_bits, p_cdc->requested_line_coding.parity, + p_cdc->requested_line_coding.data_bits, ch34x_control_complete, xfer->user_data), ); + } else { + // stage 1 failed, notify user + xfer->complete_cb = p_cdc->user_control_cb; + if (xfer->complete_cb) { + xfer->complete_cb(xfer); + } + } +} + +// 2 stages: set baudrate (stage1) + set data format (stage2) static bool ch34x_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { -// p_cdc->baudrate_requested = line_coding->bit_rate; -// p_cdc->user_control_cb = complete_cb; -// uint8_t factor, divisor, lcr; -// TU_ASSERT (ch34x_get_factor_divisor(line_coding->bit_rate, &factor, &divisor)); -// TU_ASSERT (ch34x_get_lcr(line_coding, &lcr)); -// TU_ASSERT (ch34x_control_out(p_cdc, CH34X_REQ_SERIAL_INIT, (uint16_t) (lcr << 8 | 0x9c), (uint16_t) (factor << 8 | 0x80 | divisor), -// complete_cb ? ch34x_control_complete : NULL, user_data)); - (void) p_cdc; - (void) line_coding; - (void) complete_cb; - (void) user_data; + p_cdc->requested_line_coding = *line_coding; + p_cdc->user_control_cb = complete_cb; + + if (complete_cb) { + // stage 1 set baudrate + TU_ASSERT(ch34x_write_reg_baudrate(p_cdc, line_coding->bit_rate, + ch34x_set_line_coding_stage1_complete, user_data)); + } else { + // sync call + xfer_result_t result; + + // stage 1 set baudrate + TU_ASSERT(ch34x_write_reg_baudrate(p_cdc, line_coding->bit_rate, NULL, (uintptr_t) &result)); + TU_VERIFY(result == XFER_RESULT_SUCCESS); + p_cdc->line_coding.bit_rate = line_coding->bit_rate; + + // stage 2 set data format + TU_ASSERT(ch34x_set_data_format(p_cdc, line_coding->stop_bits, line_coding->parity, line_coding->data_bits, + NULL, (uintptr_t) &result)); + TU_VERIFY(result == XFER_RESULT_SUCCESS); + p_cdc->line_coding.stop_bits = line_coding->stop_bits; + p_cdc->line_coding.parity = line_coding->parity; + p_cdc->line_coding.data_bits = line_coding->data_bits; + + // update transfer result, user_data is expected to point to xfer_result_t + if (user_data) { + user_data = result; + } + } return true; } diff --git a/src/class/cdc/serial/ch34x.h b/src/class/cdc/serial/ch34x.h index 3f78a3007..5def8d212 100644 --- a/src/class/cdc/serial/ch34x.h +++ b/src/class/cdc/serial/ch34x.h @@ -63,7 +63,8 @@ #define CH341_REG_0x2C 0x2C // undocumented register #define CH341_REG_0x27 0x27 // hardware flow control (cts/rts) -#define CH34X_REG16_DIVISOR_PRESCALER TU_U16(CH34X_REG_DIVISOR, CH34X_REG_PRESCALER) +#define CH34X_REG16_DIVISOR_PRESCALER TU_U16(CH34X_REG_DIVISOR, CH34X_REG_PRESCALER) +#define CH32X_REG16_LCR2_LCR TU_U16(CH34X_REG_LCR2, CH34X_REG_LCR) // modem control bits #define CH34X_BIT_RTS ( 1 << 6 ) From c196a2ed9cbd27188472d76ec428fdb24931d0b6 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 19 Jan 2024 16:04:30 +0700 Subject: [PATCH 061/454] move code around --- src/class/cdc/cdc_host.c | 94 +++++++++++++++++++++------------------- 1 file changed, 49 insertions(+), 45 deletions(-) diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 37fa30982..8965ee261 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -1223,46 +1223,12 @@ static void cp210x_process_config(tuh_xfer_t* xfer) { #if CFG_TUH_CDC_CH34X -enum { - CONFIG_CH34X_READ_VERSION = 0, - CONFIG_CH34X_SERIAL_INIT, - CONFIG_CH34X_SPECIAL_REG_WRITE, - CONFIG_CH34X_FLOW_CONTROL, - CONFIG_CH34X_MODEM_CONTROL, - CONFIG_CH34X_COMPLETE -}; - static uint8_t ch34x_get_lcr(uint8_t stop_bits, uint8_t parity, uint8_t data_bits); static uint16_t ch34x_get_divisor_prescaler(uint32_t baval); -static bool ch34x_open(uint8_t daddr, tusb_desc_interface_t const* itf_desc, uint16_t max_len) { - // CH34x Interface includes 1 vendor interface + 2 bulk + 1 interrupt endpoints - TU_VERIFY (itf_desc->bNumEndpoints == 3); - TU_VERIFY (sizeof(tusb_desc_interface_t) + 3 * sizeof(tusb_desc_endpoint_t) <= max_len); - - cdch_interface_t* p_cdc = make_new_itf(daddr, itf_desc); - TU_VERIFY (p_cdc); - - TU_LOG_DRV ("CH34x opened\r\n"); - p_cdc->serial_drid = SERIAL_DRIVER_CH34X; - - tusb_desc_endpoint_t const* desc_ep = (tusb_desc_endpoint_t const*) tu_desc_next(itf_desc); - - // data endpoints expected to be in pairs - TU_ASSERT(open_ep_stream_pair(p_cdc, desc_ep)); - desc_ep += 2; - - // Interrupt endpoint: not used for now - TU_ASSERT(TUSB_DESC_ENDPOINT == tu_desc_type(desc_ep) && - TUSB_XFER_INTERRUPT == desc_ep->bmAttributes.xfer); - TU_ASSERT(tuh_edpt_open(daddr, desc_ep)); - p_cdc->ep_notif = desc_ep->bEndpointAddress; - - return true; -} - +//------------- control requestt -------------// static bool ch34x_set_request(cdch_interface_t* p_cdc, uint8_t direction, uint8_t request, uint16_t value, - uint16_t index, uint8_t* buffer, uint16_t length, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + uint16_t index, uint8_t* buffer, uint16_t length, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { tusb_control_request_t const request_setup = { .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_DEVICE, @@ -1318,6 +1284,17 @@ static bool ch34x_write_reg(cdch_interface_t* p_cdc, uint16_t reg, uint16_t reg_ // return ch34x_control_in ( p_cdc, CH34X_REQ_READ_REG, reg, 0, buffer, buffersize, complete_cb, user_data ); //} +static bool ch34x_write_reg_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + uint16_t const div_ps = ch34x_get_divisor_prescaler(baudrate); + TU_VERIFY(div_ps != 0); + TU_ASSERT(ch34x_write_reg(p_cdc, CH34X_REG16_DIVISOR_PRESCALER, div_ps, + complete_cb, user_data)); + return true; +} + +//------------- Driver API -------------// + // internal control complete to update state such as line state, encoding static void ch34x_control_complete(tuh_xfer_t* xfer) { // CH34x only has 1 interface and use wIndex as payload and not for bInterfaceNumber @@ -1339,15 +1316,6 @@ static bool ch34x_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, ui return true; } -static bool ch34x_write_reg_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) { - uint16_t const div_ps = ch34x_get_divisor_prescaler(baudrate); - TU_VERIFY(div_ps != 0); - TU_ASSERT(ch34x_write_reg(p_cdc, CH34X_REG16_DIVISOR_PRESCALER, div_ps, - complete_cb, user_data)); - return true; -} - static bool ch34x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { p_cdc->requested_line_coding.bit_rate = baudrate; @@ -1432,6 +1400,42 @@ static bool ch34x_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, return true; } +//------------- Enumeration -------------// +enum { + CONFIG_CH34X_READ_VERSION = 0, + CONFIG_CH34X_SERIAL_INIT, + CONFIG_CH34X_SPECIAL_REG_WRITE, + CONFIG_CH34X_FLOW_CONTROL, + CONFIG_CH34X_MODEM_CONTROL, + CONFIG_CH34X_COMPLETE +}; + +static bool ch34x_open(uint8_t daddr, tusb_desc_interface_t const* itf_desc, uint16_t max_len) { + // CH34x Interface includes 1 vendor interface + 2 bulk + 1 interrupt endpoints + TU_VERIFY (itf_desc->bNumEndpoints == 3); + TU_VERIFY (sizeof(tusb_desc_interface_t) + 3 * sizeof(tusb_desc_endpoint_t) <= max_len); + + cdch_interface_t* p_cdc = make_new_itf(daddr, itf_desc); + TU_VERIFY (p_cdc); + + TU_LOG_DRV ("CH34x opened\r\n"); + p_cdc->serial_drid = SERIAL_DRIVER_CH34X; + + tusb_desc_endpoint_t const* desc_ep = (tusb_desc_endpoint_t const*) tu_desc_next(itf_desc); + + // data endpoints expected to be in pairs + TU_ASSERT(open_ep_stream_pair(p_cdc, desc_ep)); + desc_ep += 2; + + // Interrupt endpoint: not used for now + TU_ASSERT(TUSB_DESC_ENDPOINT == tu_desc_type(desc_ep) && + TUSB_XFER_INTERRUPT == desc_ep->bmAttributes.xfer); + TU_ASSERT(tuh_edpt_open(daddr, desc_ep)); + p_cdc->ep_notif = desc_ep->bEndpointAddress; + + return true; +} + static void ch34x_process_config(tuh_xfer_t* xfer) { // CH34x only has 1 interface and use wIndex as payload and not for bInterfaceNumber uint8_t const itf_num = 0; From 55cb713264a1fe531b548a05290ee8fe1289828f Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 19 Jan 2024 16:56:32 +0700 Subject: [PATCH 062/454] - add new API tuh_cdc_set_data_format() - add typedef for cdc enum --- src/class/cdc/cdc.h | 20 ++++----- src/class/cdc/cdc_host.c | 90 +++++++++++++++++++++++++++++++++++----- src/class/cdc/cdc_host.h | 13 +++--- 3 files changed, 95 insertions(+), 28 deletions(-) diff --git a/src/class/cdc/cdc.h b/src/class/cdc/cdc.h index deec32ae4..5cbd658fe 100644 --- a/src/class/cdc/cdc.h +++ b/src/class/cdc/cdc.h @@ -136,8 +136,7 @@ typedef enum{ //--------------------------------------------------------------------+ /// Communication Interface Management Element Request Codes -typedef enum -{ +typedef enum { CDC_REQUEST_SEND_ENCAPSULATED_COMMAND = 0x00, ///< is used to issue a command in the format of the supported control protocol of the Communications Class interface CDC_REQUEST_GET_ENCAPSULATED_RESPONSE = 0x01, ///< is used to request a response in the format of the supported control protocol of the Communications Class interface. CDC_REQUEST_SET_COMM_FEATURE = 0x02, @@ -180,39 +179,38 @@ typedef enum CDC_REQUEST_GET_ATM_VC_STATISTICS = 0x53, CDC_REQUEST_MDLM_SEMANTIC_MODEL = 0x60, -}cdc_management_request_t; +} cdc_management_request_t; -enum { +typedef enum { CDC_CONTROL_LINE_STATE_DTR = 0x01, CDC_CONTROL_LINE_STATE_RTS = 0x02, -}; +} cdc_control_line_state_t; -enum { +typedef enum { CDC_LINE_CODING_STOP_BITS_1 = 0, // 1 bit CDC_LINE_CODING_STOP_BITS_1_5 = 1, // 1.5 bits CDC_LINE_CODING_STOP_BITS_2 = 2, // 2 bits -}; +} cdc_line_coding_stopbits_t; // TODO Backward compatible for typos. Maybe removed in the future release #define CDC_LINE_CONDING_STOP_BITS_1 CDC_LINE_CODING_STOP_BITS_1 #define CDC_LINE_CONDING_STOP_BITS_1_5 CDC_LINE_CODING_STOP_BITS_1_5 #define CDC_LINE_CONDING_STOP_BITS_2 CDC_LINE_CODING_STOP_BITS_2 -enum { +typedef enum { CDC_LINE_CODING_PARITY_NONE = 0, CDC_LINE_CODING_PARITY_ODD = 1, CDC_LINE_CODING_PARITY_EVEN = 2, CDC_LINE_CODING_PARITY_MARK = 3, CDC_LINE_CODING_PARITY_SPACE = 4, -}; +} cdc_line_coding_parity_t; //--------------------------------------------------------------------+ // Management Element Notification (Notification Endpoint) //--------------------------------------------------------------------+ /// 6.3 Notification Codes -typedef enum -{ +typedef enum { CDC_NOTIF_NETWORK_CONNECTION = 0x00, ///< This notification allows the device to notify the host about network connection status. CDC_NOTIF_RESPONSE_AVAILABLE = 0x01, ///< This notification allows the device to notify the hostthat a response is available. This response can be retrieved with a subsequent \ref CDC_REQUEST_GET_ENCAPSULATED_RESPONSE request. CDC_NOTIF_AUX_JACK_HOOK_STATE = 0x08, diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 8965ee261..f5182efc2 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -90,9 +90,10 @@ static cdch_interface_t cdch_data[CFG_TUH_CDC]; static bool acm_open(uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len); static void acm_process_config(tuh_xfer_t* xfer); +static bool acm_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +static bool acm_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, tuh_xfer_cb_t complete_cb, uintptr_t user_data); static bool acm_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data); static bool acm_set_control_line_state(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data); -static bool acm_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data); //------------- FTDI prototypes -------------// #if CFG_TUH_CDC_FTDI @@ -100,15 +101,13 @@ static bool acm_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfe static uint16_t const ftdi_vid_pid_list[][2] = {CFG_TUH_CDC_FTDI_VID_PID_LIST}; -// Store last request baudrate since divisor to baudrate is not easy -// static uint32_t _ftdi_requested_baud; - static bool ftdi_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len); static void ftdi_process_config(tuh_xfer_t* xfer); +static bool ftdi_sio_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +static bool ftdi_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, tuh_xfer_cb_t complete_cb, uintptr_t user_data); static bool ftdi_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data); static bool ftdi_sio_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data); -static bool ftdi_sio_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data); #endif //------------- CP210X prototypes -------------// @@ -120,9 +119,10 @@ static uint16_t const cp210x_vid_pid_list[][2] = {CFG_TUH_CDC_CP210X_VID_PID_LIS static bool cp210x_open(uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len); static void cp210x_process_config(tuh_xfer_t* xfer); +static bool cp210x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +static bool cp210x_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, tuh_xfer_cb_t complete_cb, uintptr_t user_data); static bool cp210x_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data); static bool cp210x_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data); -static bool cp210x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data); #endif //------------- CH34x prototypes -------------// @@ -131,16 +131,16 @@ static bool cp210x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_ static uint16_t const ch34x_vid_pid_list[][2] = {CFG_TUH_CDC_CH34X_VID_PID_LIST}; -static bool ch34x_open ( uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len ); -static void ch34x_process_config ( tuh_xfer_t* xfer ); +static bool ch34x_open(uint8_t daddr, tusb_desc_interface_t const* itf_desc, uint16_t max_len); +static void ch34x_process_config(tuh_xfer_t* xfer); +static bool ch34x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +static bool ch34x_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, tuh_xfer_cb_t complete_cb, uintptr_t user_data); static bool ch34x_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data); -static bool ch34x_set_modem_ctrl ( cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data ); -static bool ch34x_set_baudrate ( cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data ); +static bool ch34x_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data); #endif //------------- Common -------------// - enum { SERIAL_DRIVER_ACM = 0, @@ -166,6 +166,7 @@ typedef struct { void (*const process_set_config)(tuh_xfer_t* xfer); bool (*const set_control_line_state)(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data); bool (*const set_baudrate)(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data); + bool (*const set_data_format)(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, tuh_xfer_cb_t complete_cb, uintptr_t user_data); bool (*const set_line_coding)(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data); } cdch_serial_driver_t; @@ -178,6 +179,7 @@ static const cdch_serial_driver_t serial_drivers[] = { .process_set_config = acm_process_config, .set_control_line_state = acm_set_control_line_state, .set_baudrate = acm_set_baudrate, + .set_data_format = acm_set_data_format, .set_line_coding = acm_set_line_coding }, @@ -189,6 +191,7 @@ static const cdch_serial_driver_t serial_drivers[] = { .process_set_config = ftdi_process_config, .set_control_line_state = ftdi_sio_set_modem_ctrl, .set_baudrate = ftdi_sio_set_baudrate, + .set_data_format = ftdi_set_data_format, .set_line_coding = ftdi_set_line_coding }, #endif @@ -201,6 +204,7 @@ static const cdch_serial_driver_t serial_drivers[] = { .process_set_config = cp210x_process_config, .set_control_line_state = cp210x_set_modem_ctrl, .set_baudrate = cp210x_set_baudrate, + .set_data_format = cp210x_set_data_format, .set_line_coding = cp210x_set_line_coding }, #endif @@ -213,6 +217,7 @@ static const cdch_serial_driver_t serial_drivers[] = { .process_set_config = ch34x_process_config, .set_control_line_state = ch34x_set_modem_ctrl, .set_baudrate = ch34x_set_baudrate, + .set_data_format = ch34x_set_data_format, .set_line_coding = ch34x_set_line_coding }, #endif @@ -562,6 +567,32 @@ bool tuh_cdc_set_baudrate(uint8_t idx, uint32_t baudrate, tuh_xfer_cb_t complete } } +bool tuh_cdc_set_data_format(uint8_t idx, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + cdch_interface_t* p_cdc = get_itf(idx); + TU_VERIFY(p_cdc && p_cdc->serial_drid < SERIAL_DRIVER_COUNT); + cdch_serial_driver_t const* driver = &serial_drivers[p_cdc->serial_drid]; + + if (complete_cb) { + return driver->set_data_format(p_cdc, stop_bits, parity, data_bits, complete_cb, user_data); + } else { + // blocking + xfer_result_t result = XFER_RESULT_INVALID; + bool ret = driver->set_data_format(p_cdc, stop_bits, parity, data_bits, complete_cb, (uintptr_t) &result); + + if (user_data) { + // user_data is not NULL, return result via user_data + *((xfer_result_t*) user_data) = result; + } + + TU_VERIFY(ret && result == XFER_RESULT_SUCCESS); + p_cdc->line_coding.stop_bits = stop_bits; + p_cdc->line_coding.parity = parity; + p_cdc->line_coding.data_bits = data_bits; + return true; + } +} + bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc && p_cdc->serial_drid < SERIAL_DRIVER_COUNT); @@ -900,6 +931,19 @@ static bool acm_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const return true; } +static bool acm_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + TU_LOG_DRV("CDC ACM Set Data Format\r\n"); + + cdc_line_coding_t line_coding; + line_coding.bit_rate = p_cdc->line_coding.bit_rate; + line_coding.stop_bits = stop_bits; + line_coding.parity = parity; + line_coding.data_bits = data_bits; + + return acm_set_line_coding(p_cdc, &line_coding, complete_cb, user_data); +} + static bool acm_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { TU_VERIFY(p_cdc->acm_capability.support_line_request); cdc_line_coding_t line_coding = p_cdc->line_coding; @@ -968,6 +1012,18 @@ static bool ftdi_sio_reset(cdch_interface_t* p_cdc, tuh_xfer_cb_t complete_cb, u return ftdi_sio_set_request(p_cdc, FTDI_SIO_RESET, FTDI_SIO_RESET_SIO, complete_cb, user_data); } +static bool ftdi_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + (void) p_cdc; + (void) stop_bits; + (void) parity; + (void) data_bits; + (void) complete_cb; + (void) user_data; + // TODO not implemented yet + return false; +} + static bool ftdi_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { (void) p_cdc; (void) line_coding; @@ -1161,6 +1217,18 @@ static bool cp210x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_ complete_cb ? cdch_internal_control_complete : NULL, user_data); } +static bool cp210x_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + (void) p_cdc; + (void) stop_bits; + (void) parity; + (void) data_bits; + (void) complete_cb; + (void) user_data; + // TODO not implemented yet + return false; +} + static bool cp210x_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { TU_LOG_DRV("CDC CP210x Set Control Line State\r\n"); p_cdc->user_control_cb = complete_cb; diff --git a/src/class/cdc/cdc_host.h b/src/class/cdc/cdc_host.h index 9e5edd94e..d512a23a5 100644 --- a/src/class/cdc/cdc_host.h +++ b/src/class/cdc/cdc_host.h @@ -148,8 +148,11 @@ bool tuh_cdc_set_control_line_state(uint8_t idx, uint16_t line_state, tuh_xfer_c // Request to set baudrate bool tuh_cdc_set_baudrate(uint8_t idx, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data); -// Request to Set Line Coding (ACM only) -// Should only use if you don't work with serial devices such as FTDI/CP210x +// Request to set data format +bool tuh_cdc_set_data_format(uint8_t idx, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, tuh_xfer_cb_t complete_cb, uintptr_t user_data); + +// Request to Set Line Coding = baudrate + data format +// Note: only implemented by ACM and CH34x, not supported by FTDI and CP210x yet bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data); // Request to Get Line Coding (ACM only) @@ -159,15 +162,13 @@ bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding, // Connect by set both DTR, RTS TU_ATTR_ALWAYS_INLINE static inline -bool tuh_cdc_connect(uint8_t idx, tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ +bool tuh_cdc_connect(uint8_t idx, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return tuh_cdc_set_control_line_state(idx, CDC_CONTROL_LINE_STATE_DTR | CDC_CONTROL_LINE_STATE_RTS, complete_cb, user_data); } // Disconnect by clear both DTR, RTS TU_ATTR_ALWAYS_INLINE static inline -bool tuh_cdc_disconnect(uint8_t idx, tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ +bool tuh_cdc_disconnect(uint8_t idx, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return tuh_cdc_set_control_line_state(idx, 0x00, complete_cb, user_data); } From 87d509d416ea7c250f4256f897f6cc9a7b7d2121 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 20 Jan 2024 01:42:31 +0700 Subject: [PATCH 063/454] make CFG_TUH_CDC_LINE_CODING_ON_ENUM optional for ch34x --- examples/host/cdc_msc_hid/src/cdc_app.c | 8 ++++++-- src/class/cdc/cdc_host.c | 19 ++++++++++++++----- src/class/cdc/serial/ch34x.h | 12 +----------- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/examples/host/cdc_msc_hid/src/cdc_app.c b/examples/host/cdc_msc_hid/src/cdc_app.c index 81052047c..e275e7943 100644 --- a/examples/host/cdc_msc_hid/src/cdc_app.c +++ b/examples/host/cdc_msc_hid/src/cdc_app.c @@ -85,13 +85,17 @@ void tuh_cdc_mount_cb(uint8_t idx) { itf_info.desc.bInterfaceNumber); #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM - // CFG_TUH_CDC_LINE_CODING_ON_ENUM must be defined for line coding is set by tinyusb in enumeration - // otherwise you need to call tuh_cdc_set_line_coding() first + // If CFG_TUH_CDC_LINE_CODING_ON_ENUM is defined, line coding will be set by tinyusb stack + // while eneumerating new cdc device cdc_line_coding_t line_coding = {0}; if (tuh_cdc_get_local_line_coding(idx, &line_coding)) { printf(" Baudrate: %lu, Stop Bits : %u\r\n", line_coding.bit_rate, line_coding.stop_bits); printf(" Parity : %u, Data Width: %u\r\n", line_coding.parity, line_coding.data_bits); } +#else + // Set Line Coding upon mounted + cdc_line_coding_t new_line_coding = { 115200, CDC_LINE_CODING_STOP_BITS_1, CDC_LINE_CODING_PARITY_NONE, 8 }; + tuh_cdc_set_line_coding(idx, &new_line_coding, NULL, 0); #endif } diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index f5182efc2..cd948243d 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -1510,10 +1510,11 @@ static void ch34x_process_config(tuh_xfer_t* xfer) { uint8_t const idx = tuh_cdc_itf_get_index(xfer->daddr, itf_num); cdch_interface_t* p_cdc = get_itf(idx); uintptr_t const state = xfer->user_data; - cdc_line_coding_t const line_coding = CFG_TUH_CDC_LINE_CODING_ON_ENUM_CH34X; uint8_t buffer[2]; // TODO remove TU_ASSERT (p_cdc,); + // TODO check xfer->result + switch (state) { case CONFIG_CH34X_READ_VERSION: TU_LOG_DRV("[%u] CDCh CH34x attempt to read Chip Version\r\n", p_cdc->daddr); @@ -1527,20 +1528,28 @@ static void ch34x_process_config(tuh_xfer_t* xfer) { // only versions >= 0x30 are tested, below 0x30 seems having other programming, see drivers from WCH vendor, Linux kernel and FreeBSD TU_ASSERT (version >= 0x30,); + #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM + cdc_line_coding_t const line_coding = CFG_TUH_CDC_LINE_CODING_ON_ENUM; + uint8_t const lcr = ch34x_get_lcr(line_coding.stop_bits, line_coding.parity, line_coding.data_bits); + uint16_t const first_arg = tu_u16(lcr, 0x9c); uint16_t const div_ps = ch34x_get_divisor_prescaler(line_coding.bit_rate); TU_ASSERT(div_ps != 0, ); - - uint8_t const lcr = ch34x_get_lcr(line_coding.stop_bits, line_coding.parity, line_coding.data_bits); + #else + uint16_t const first_arg = 0; + uint16_t const div_ps = 0; + #endif // Init CH34x with line coding - TU_ASSERT (ch34x_control_out(p_cdc, CH34X_REQ_SERIAL_INIT, tu_u16(lcr, 0x9c), div_ps, + TU_ASSERT (ch34x_control_out(p_cdc, CH34X_REQ_SERIAL_INIT, first_arg, div_ps, ch34x_process_config, CONFIG_CH34X_SPECIAL_REG_WRITE),); break; } case CONFIG_CH34X_SPECIAL_REG_WRITE: // do special reg write, purpose unknown, overtaken from WCH driver - p_cdc->line_coding = line_coding; + #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM + p_cdc->line_coding = ((cdc_line_coding_t) CFG_TUH_CDC_LINE_CODING_ON_ENUM); + #endif TU_ASSERT (ch34x_write_reg(p_cdc, 0x0f2c, 0x0007, ch34x_process_config, CONFIG_CH34X_FLOW_CONTROL),); break; diff --git a/src/class/cdc/serial/ch34x.h b/src/class/cdc/serial/ch34x.h index 5def8d212..b9121afb3 100644 --- a/src/class/cdc/serial/ch34x.h +++ b/src/class/cdc/serial/ch34x.h @@ -27,21 +27,11 @@ #ifndef _CH34X_H_ #define _CH34X_H_ -// For simplicity, only the name CH34X is used here, -// but specifically only CH340 and CH341 are supported. - -// There is no official documentation for the CH34x chips. Reference can be found +// There is no official documentation for the CH34x (CH340, CH341) chips. Reference can be found // - https://github.com/WCHSoftGroup/ch341ser_linux // - https://github.com/torvalds/linux/blob/master/drivers/usb/serial/ch341.c // - https://github.com/freebsd/freebsd-src/blob/main/sys/dev/usb/serial/uchcom.c -// set line_coding @ enumeration -#ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM -#define CFG_TUH_CDC_LINE_CODING_ON_ENUM_CH34X CFG_TUH_CDC_LINE_CODING_ON_ENUM -#else // this default is necessary to work properly -#define CFG_TUH_CDC_LINE_CODING_ON_ENUM_CH34X { 9600, CDC_LINE_CONDING_STOP_BITS_1, CDC_LINE_CODING_PARITY_NONE, 8 } -#endif - // USB requests #define CH34X_REQ_READ_VERSION 0x5F // dec 95 #define CH34X_REQ_WRITE_REG 0x9A // dec 154 From 769a237b19bbe5254e1c83869b463c79afb1af34 Mon Sep 17 00:00:00 2001 From: IngHK Date: Sat, 20 Jan 2024 20:34:50 +0100 Subject: [PATCH 064/454] accumulated review changes --- src/class/cdc/cdc_host.c | 68 ++++++++++++++++-------------------- src/class/cdc/serial/ch34x.h | 7 ++++ 2 files changed, 38 insertions(+), 37 deletions(-) diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index cd948243d..7adaa0c8c 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -401,7 +401,9 @@ bool tuh_cdc_read_clear (uint8_t idx) { // Control Endpoint API //--------------------------------------------------------------------+ -static void process_internal_control_complete(cdch_interface_t* p_cdc, tuh_xfer_t* xfer) { +static void process_internal_control_complete(tuh_xfer_t* xfer, uint8_t itf_num) { + uint8_t idx = tuh_cdc_itf_get_index(xfer->daddr, itf_num); + cdch_interface_t* p_cdc = get_itf(idx); TU_ASSERT(p_cdc, ); uint16_t const value = tu_le16toh(xfer->setup->wValue); @@ -515,10 +517,7 @@ static void process_internal_control_complete(cdch_interface_t* p_cdc, tuh_xfer_ // internal control complete to update state such as line state, encoding static void cdch_internal_control_complete(tuh_xfer_t* xfer) { uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); - uint8_t idx = tuh_cdc_itf_get_index(xfer->daddr, itf_num); - cdch_interface_t* p_cdc = get_itf(idx); - - process_internal_control_complete(p_cdc, xfer); + process_internal_control_complete(xfer, itf_num); } bool tuh_cdc_set_control_line_state(uint8_t idx, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { @@ -1294,7 +1293,8 @@ static void cp210x_process_config(tuh_xfer_t* xfer) { static uint8_t ch34x_get_lcr(uint8_t stop_bits, uint8_t parity, uint8_t data_bits); static uint16_t ch34x_get_divisor_prescaler(uint32_t baval); -//------------- control requestt -------------// +//------------- control request -------------// + static bool ch34x_set_request(cdch_interface_t* p_cdc, uint8_t direction, uint8_t request, uint16_t value, uint16_t index, uint8_t* buffer, uint16_t length, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { tusb_control_request_t const request_setup = { @@ -1366,10 +1366,7 @@ static bool ch34x_write_reg_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, // internal control complete to update state such as line state, encoding static void ch34x_control_complete(tuh_xfer_t* xfer) { // CH34x only has 1 interface and use wIndex as payload and not for bInterfaceNumber - uint8_t const itf_num = 0; - uint8_t const idx = tuh_cdc_itf_get_index(xfer->daddr, itf_num); - cdch_interface_t* p_cdc = get_itf(idx); - process_internal_control_complete(p_cdc, xfer); + process_internal_control_complete(xfer, 0); } static bool ch34x_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, @@ -1379,6 +1376,7 @@ static bool ch34x_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, ui p_cdc->requested_line_coding.data_bits = data_bits; uint8_t const lcr = ch34x_get_lcr(stop_bits, parity, data_bits); + TU_VERIFY(lcr != 0); TU_ASSERT (ch34x_control_out(p_cdc, CH34X_REQ_WRITE_REG, CH32X_REG16_LCR2_LCR, lcr, complete_cb ? ch34x_control_complete : NULL, user_data)); return true; @@ -1527,35 +1525,26 @@ static void ch34x_process_config(tuh_xfer_t* xfer) { TU_LOG_DRV("[%u] CDCh CH34x Chip Version = %02x\r\n", p_cdc->daddr, version); // only versions >= 0x30 are tested, below 0x30 seems having other programming, see drivers from WCH vendor, Linux kernel and FreeBSD TU_ASSERT (version >= 0x30,); - - #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM - cdc_line_coding_t const line_coding = CFG_TUH_CDC_LINE_CODING_ON_ENUM; - uint8_t const lcr = ch34x_get_lcr(line_coding.stop_bits, line_coding.parity, line_coding.data_bits); - uint16_t const first_arg = tu_u16(lcr, 0x9c); + // init CH34x with line coding + cdc_line_coding_t const line_coding = CFG_TUH_CDC_LINE_CODING_ON_ENUM_CH34X; uint16_t const div_ps = ch34x_get_divisor_prescaler(line_coding.bit_rate); TU_ASSERT(div_ps != 0, ); - #else - uint16_t const first_arg = 0; - uint16_t const div_ps = 0; - #endif - - // Init CH34x with line coding - TU_ASSERT (ch34x_control_out(p_cdc, CH34X_REQ_SERIAL_INIT, first_arg, div_ps, + uint8_t const lcr = ch34x_get_lcr(line_coding.stop_bits, line_coding.parity, line_coding.data_bits); + TU_ASSERT(lcr != 0, ); + TU_ASSERT (ch34x_control_out(p_cdc, CH34X_REQ_SERIAL_INIT, tu_u16(lcr, 0x9c), div_ps, ch34x_process_config, CONFIG_CH34X_SPECIAL_REG_WRITE),); break; } case CONFIG_CH34X_SPECIAL_REG_WRITE: - // do special reg write, purpose unknown, overtaken from WCH driver - #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM - p_cdc->line_coding = ((cdc_line_coding_t) CFG_TUH_CDC_LINE_CODING_ON_ENUM); - #endif - TU_ASSERT (ch34x_write_reg(p_cdc, 0x0f2c, 0x0007, ch34x_process_config, CONFIG_CH34X_FLOW_CONTROL),); + // overtake line coding and do special reg write, purpose unknown, overtaken from WCH driver + p_cdc->line_coding = ((cdc_line_coding_t) CFG_TUH_CDC_LINE_CODING_ON_ENUM_CH34X); + TU_ASSERT (ch34x_write_reg(p_cdc, TU_U16(CH341_REG_0x0F, CH341_REG_0x2C), 0x0007, ch34x_process_config, CONFIG_CH34X_FLOW_CONTROL),); break; case CONFIG_CH34X_FLOW_CONTROL: // no hardware flow control - TU_ASSERT (ch34x_write_reg(p_cdc, 0x2727, 0x0000, ch34x_process_config, CONFIG_CH34X_MODEM_CONTROL),); + TU_ASSERT (ch34x_write_reg(p_cdc, TU_U16(CH341_REG_0x27, CH341_REG_0x27), 0x0000, ch34x_process_config, CONFIG_CH34X_MODEM_CONTROL),); break; case CONFIG_CH34X_MODEM_CONTROL: @@ -1581,6 +1570,7 @@ static uint16_t ch34x_get_divisor_prescaler(uint32_t baval) { uint8_t b; uint32_t c; + TU_VERIFY(baval != 0, 0); switch (baval) { case 921600: a = 0xf3; @@ -1606,7 +1596,7 @@ static uint16_t ch34x_get_divisor_prescaler(uint32_t baval) { b = 0; c = 11719; } - a = (unsigned char) (c / baval); + a = (uint8_t) (c / baval); if (a == 0 || a == 0xFF) { return 0; } @@ -1620,29 +1610,33 @@ static uint16_t ch34x_get_divisor_prescaler(uint32_t baval) { // reg divisor = a, reg prescaler = b // According to linux code we need to set bit 7 of UCHCOM_REG_BPS_PRE, // otherwise the chip will buffer data. - return (uint16_t) (a << 8 | 0x80 | b); + return (uint16_t) ((uint16_t)a << 8 | 0x80 | b); } // calculate lcr value from data coding static uint8_t ch34x_get_lcr(uint8_t stop_bits, uint8_t parity, uint8_t data_bits) { uint8_t lcr = CH34X_LCR_ENABLE_RX | CH34X_LCR_ENABLE_TX; - TU_VERIFY(data_bits >= 5, 0); + TU_VERIFY(data_bits >= 5 && data_bits <= 8, 0); lcr |= (uint8_t) (data_bits - 5); - if (parity) { - lcr |= CH34X_LCR_ENABLE_PAR; - } switch(parity) { + case CDC_LINE_CODING_PARITY_NONE: + break; + + case CDC_LINE_CODING_PARITY_ODD: + lcr |= CH34X_LCR_ENABLE_PAR; + break; + case CDC_LINE_CODING_PARITY_EVEN: - lcr |= CH34X_LCR_PAR_EVEN; + lcr |= CH34X_LCR_ENABLE_PAR | CH34X_LCR_PAR_EVEN; break; case CDC_LINE_CODING_PARITY_MARK: - lcr |= CH34X_LCR_MARK_SPACE; + lcr |= CH34X_LCR_ENABLE_PAR | CH34X_LCR_MARK_SPACE; break; case CDC_LINE_CODING_PARITY_SPACE: - lcr |= CH34X_LCR_MARK_SPACE | CH34X_LCR_PAR_EVEN; + lcr |= CH34X_LCR_ENABLE_PAR | CH34X_LCR_MARK_SPACE | CH34X_LCR_PAR_EVEN; break; default: break; diff --git a/src/class/cdc/serial/ch34x.h b/src/class/cdc/serial/ch34x.h index b9121afb3..c18066f57 100644 --- a/src/class/cdc/serial/ch34x.h +++ b/src/class/cdc/serial/ch34x.h @@ -32,6 +32,13 @@ // - https://github.com/torvalds/linux/blob/master/drivers/usb/serial/ch341.c // - https://github.com/freebsd/freebsd-src/blob/main/sys/dev/usb/serial/uchcom.c +// set line_coding @ enumeration +#ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM +#define CFG_TUH_CDC_LINE_CODING_ON_ENUM_CH34X CFG_TUH_CDC_LINE_CODING_ON_ENUM +#else // this default is necessary to work properly +#define CFG_TUH_CDC_LINE_CODING_ON_ENUM_CH34X { 9600, CDC_LINE_CONDING_STOP_BITS_1, CDC_LINE_CODING_PARITY_NONE, 8 } +#endif + // USB requests #define CH34X_REQ_READ_VERSION 0x5F // dec 95 #define CH34X_REQ_WRITE_REG 0x9A // dec 154 From af3c6be79fe9a9829f30831bd7525d2a22cb5529 Mon Sep 17 00:00:00 2001 From: Jonathan Zentgraf Date: Sat, 20 Jan 2024 20:16:54 -0500 Subject: [PATCH 065/454] msc_device: Fix check for including MSC lookup tables The _msc_scsi_cmd_lookup and _msc_scsi_cmd_table variables are needed when logging is enabled for the MSC device via CFG_TUD_MSC_LOG_LEVEL. Update the preprocessor check around them to use that definition when deciding whether to define those variables. Closes #2419 --- src/class/msc/msc_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index 2589dcd2c..c145d86a6 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -203,7 +203,7 @@ uint8_t rdwr10_validate_cmd(msc_cbw_t const* cbw) //--------------------------------------------------------------------+ // Debug //--------------------------------------------------------------------+ -#if CFG_TUSB_DEBUG >= 2 +#if CFG_TUSB_DEBUG >= CFG_TUD_MSC_LOG_LEVEL TU_ATTR_UNUSED tu_static tu_lookup_entry_t const _msc_scsi_cmd_lookup[] = { From 1c9a839401cb7323f93202f600c6f3148100e10a Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Tue, 23 Jan 2024 13:48:09 +0100 Subject: [PATCH 066/454] audio_device: Fix unused variable warning In some configurations local variable p_desc_parse_for_params is declared and never used resulting in warning that can be escalated to build error (for mynewt) Now variable is surrounded with same preprocessor condition as function that uses it audiod_parse_for_AS_params() --- 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 d438d0715..4adc558a6 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -1729,7 +1729,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * // 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) { -#if CFG_TUD_AUDIO_ENABLE_ENCODING || CFG_TUD_AUDIO_ENABLE_DECODING || CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL +#if (CFG_TUD_AUDIO_ENABLE_EP_IN && (CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL || CFG_TUD_AUDIO_ENABLE_ENCODING)) || (CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING) uint8_t const * p_desc_parse_for_params = p_desc; #endif // From this point forward follow the EP descriptors associated to the current alternate setting interface - Open EPs if necessary From 82218c8d6875947fee29e9b9a0b48b87bb587281 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 24 Jan 2024 00:43:23 +0700 Subject: [PATCH 067/454] retry flashih a few time due to random failed by s3 --- test/hil/hil_test.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index 7c662aeea..544a4eb39 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -364,8 +364,14 @@ def main(config_file, board): print(f' {test} ...', end='') - # flash firmware - ret = globals()[f'flash_{flasher}'](item, fw) + # flash firmware. It may fail randomly, retry a few times + for i in range(3): + ret = globals()[f'flash_{flasher}'](item, fw) + if ret.returncode == 0: + break + else: + time.sleep(1) + assert ret.returncode == 0, 'Flash failed\n' + ret.stdout.decode() # run test From e819a28a8bfd6ec3e2279d711b27eb05d3044f61 Mon Sep 17 00:00:00 2001 From: Jerry Palacios Date: Tue, 23 Jan 2024 16:49:44 -0600 Subject: [PATCH 068/454] frdm-mcxn947 folder created frdm-mcxn947 folder created. Led and button pin modified compared to mcxn947brk board --- hw/bsp/mcx/boards/frdm-mcxn947/board.cmake | 21 ++ hw/bsp/mcx/boards/frdm-mcxn947/board.h | 66 ++++ hw/bsp/mcx/boards/frdm-mcxn947/board.mk | 11 + hw/bsp/mcx/boards/frdm-mcxn947/clock_config.c | 338 ++++++++++++++++++ hw/bsp/mcx/boards/frdm-mcxn947/clock_config.h | 177 +++++++++ hw/bsp/mcx/boards/frdm-mcxn947/pin_mux.c | 141 ++++++++ hw/bsp/mcx/boards/frdm-mcxn947/pin_mux.h | 51 +++ 7 files changed, 805 insertions(+) create mode 100644 hw/bsp/mcx/boards/frdm-mcxn947/board.cmake create mode 100644 hw/bsp/mcx/boards/frdm-mcxn947/board.h create mode 100644 hw/bsp/mcx/boards/frdm-mcxn947/board.mk create mode 100644 hw/bsp/mcx/boards/frdm-mcxn947/clock_config.c create mode 100644 hw/bsp/mcx/boards/frdm-mcxn947/clock_config.h create mode 100644 hw/bsp/mcx/boards/frdm-mcxn947/pin_mux.c create mode 100644 hw/bsp/mcx/boards/frdm-mcxn947/pin_mux.h diff --git a/hw/bsp/mcx/boards/frdm-mcxn947/board.cmake b/hw/bsp/mcx/boards/frdm-mcxn947/board.cmake new file mode 100644 index 000000000..8c3280743 --- /dev/null +++ b/hw/bsp/mcx/boards/frdm-mcxn947/board.cmake @@ -0,0 +1,21 @@ +set(MCU_VARIANT MCXN947) +set(MCU_CORE MCXN947_cm33_core0) + +set(JLINK_DEVICE MCXN947_M33_0) +set(PYOCD_TARGET MCXN947) +set(NXPLINK_DEVICE MCXN947:MCXN947) + +set(PORT 1) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + CPU_MCXN947VDF_cm33_core0 + BOARD_TUD_RHPORT=${PORT} + # port 0 is fullspeed, port 1 is highspeed + BOARD_TUD_MAX_SPEED=$ + ) + target_sources(${TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/clock_config.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/pin_mux.c + ) +endfunction() diff --git a/hw/bsp/mcx/boards/frdm-mcxn947/board.h b/hw/bsp/mcx/boards/frdm-mcxn947/board.h new file mode 100644 index 000000000..acb73363f --- /dev/null +++ b/hw/bsp/mcx/boards/frdm-mcxn947/board.h @@ -0,0 +1,66 @@ +/* + * 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 + +// LED +#define LED_GPIO GPIO0 +#define LED_CLK kCLOCK_Gpio0 +#define LED_PIN 10 // red +#define LED_STATE_ON 0 + +// WAKE button (Dummy, use unused pin +#define BUTTON_GPIO GPIO0 +#define BUTTON_CLK kCLOCK_Gpio0 +#define BUTTON_PIN 23 +#define BUTTON_STATE_ACTIVE 0 + +// UART +#define UART_DEV LPUART4 + +static inline void board_uart_init_clock(void) { + /* attach FRO 12M to FLEXCOMM4 */ + CLOCK_SetClkDiv(kCLOCK_DivFlexcom4Clk, 1u); + CLOCK_AttachClk(kFRO12M_to_FLEXCOMM4); + RESET_ClearPeripheralReset(kFC4_RST_SHIFT_RSTn); +} + +//#define UART_RX_PINMUX 0, 24, IOCON_PIO_DIG_FUNC1_EN +//#define UART_TX_PINMUX 0, 25, IOCON_PIO_DIG_FUNC1_EN + +// XTAL +#define XTAL0_CLK_HZ (24 * 1000 * 1000U) + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/hw/bsp/mcx/boards/frdm-mcxn947/board.mk b/hw/bsp/mcx/boards/frdm-mcxn947/board.mk new file mode 100644 index 000000000..aaad5e73e --- /dev/null +++ b/hw/bsp/mcx/boards/frdm-mcxn947/board.mk @@ -0,0 +1,11 @@ +MCU_VARIANT = MCXN947 +MCU_CORE = MCXN947_cm33_core0 +PORT ?= 1 + +CFLAGS += -DCPU_MCXN947VDF_cm33_core0 + +JLINK_DEVICE = MCXN947_M33_0 +PYOCD_TARGET = MCXN947 + +# flash using pyocd +flash: flash-jlink diff --git a/hw/bsp/mcx/boards/frdm-mcxn947/clock_config.c b/hw/bsp/mcx/boards/frdm-mcxn947/clock_config.c new file mode 100644 index 000000000..37d2b4dfc --- /dev/null +++ b/hw/bsp/mcx/boards/frdm-mcxn947/clock_config.c @@ -0,0 +1,338 @@ +/* + * Copyright 2022 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ +/* + * How to setup clock using clock driver functions: + * + * 1. Setup clock sources. + * + * 2. Set up wait states of the flash. + * + * 3. Set up all dividers. + * + * 4. Set up all selectors to provide selected clocks. + * + */ + +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Clocks v10.0 +processor: MCXN947 +package_id: MCXN947VDF +mcu_data: ksdk2_0 +processor_version: 0.12.3 +board: MCX-N9XX-EVK + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +#include "clock_config.h" +#include "fsl_clock.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ +/* System clock frequency. */ +// extern uint32_t SystemCoreClock; + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ +void BOARD_InitBootClocks(void) +{ + BOARD_BootClockPLL150M(); +} + +/******************************************************************************* + ******************** Configuration BOARD_BootClockFRO12M ********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockFRO12M +outputs: +- {id: CLK_144M_clock.outFreq, value: 144 MHz} +- {id: CLK_48M_clock.outFreq, value: 48 MHz} +- {id: FRO_12M_clock.outFreq, value: 12 MHz} +- {id: MAIN_clock.outFreq, value: 12 MHz} +- {id: Slow_clock.outFreq, value: 3 MHz} +- {id: System_clock.outFreq, value: 12 MHz} +- {id: gdet_clock.outFreq, value: 48 MHz} +- {id: trng_clock.outFreq, value: 48 MHz} +settings: +- {id: SCGMode, value: SIRC} +- {id: SCG.SCSSEL.sel, value: SCG.SIRC} +- {id: SCG_FIRCCSR_FIRCEN_CFG, value: Disabled} +- {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} +- {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockFRO12M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockFRO12M configuration + ******************************************************************************/ +void BOARD_BootClockFRO12M(void) +{ + /*!< Enable SCG clock */ + CLOCK_EnableClock(kCLOCK_Scg); + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO12M */ + + /*!< Set up dividers */ + CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U); /*!< Set AHBCLKDIV divider to value 1 */ + + /* Set SystemCoreClock variable */ + SystemCoreClock = BOARD_BOOTCLOCKFRO12M_CORE_CLOCK; +} + +/******************************************************************************* + ******************* Configuration BOARD_BootClockFROHF48M ********************* + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockFROHF48M +outputs: +- {id: CLK_144M_clock.outFreq, value: 144 MHz} +- {id: CLK_48M_clock.outFreq, value: 48 MHz} +- {id: FRO_12M_clock.outFreq, value: 12 MHz} +- {id: FRO_HF_clock.outFreq, value: 48 MHz} +- {id: MAIN_clock.outFreq, value: 48 MHz} +- {id: Slow_clock.outFreq, value: 12 MHz} +- {id: System_clock.outFreq, value: 48 MHz} +- {id: gdet_clock.outFreq, value: 48 MHz} +- {id: trng_clock.outFreq, value: 48 MHz} +settings: +- {id: SYSCON.FLEXCAN0CLKSEL.sel, value: NO_CLOCK} +- {id: SYSCON.FLEXCAN1CLKSEL.sel, value: NO_CLOCK} +- {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} +- {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockFROHF48M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockFROHF48M configuration + ******************************************************************************/ +void BOARD_BootClockFROHF48M(void) +{ + /*!< Enable SCG clock */ + CLOCK_EnableClock(kCLOCK_Scg); + + CLOCK_SetupFROHFClocking(48000000U); /*!< Enable FRO HF(48MHz) output */ + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO_HF */ + + /*!< Set up dividers */ + CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U); /*!< Set AHBCLKDIV divider to value 1 */ + + /* Set SystemCoreClock variable */ + SystemCoreClock = BOARD_BOOTCLOCKFROHF48M_CORE_CLOCK; +} + +/******************************************************************************* + ******************* Configuration BOARD_BootClockFROHF144M ******************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockFROHF144M +outputs: +- {id: CLK_144M_clock.outFreq, value: 144 MHz} +- {id: CLK_48M_clock.outFreq, value: 48 MHz} +- {id: FRO_12M_clock.outFreq, value: 12 MHz} +- {id: FRO_HF_clock.outFreq, value: 144 MHz} +- {id: MAIN_clock.outFreq, value: 144 MHz} +- {id: Slow_clock.outFreq, value: 18 MHz} +- {id: System_clock.outFreq, value: 72 MHz} +- {id: gdet_clock.outFreq, value: 48 MHz} +- {id: trng_clock.outFreq, value: 48 MHz} +settings: +- {id: SYSCON.AHBCLKDIV.scale, value: '2', locked: true} +- {id: SYSCON.FLEXCAN0CLKSEL.sel, value: NO_CLOCK} +- {id: SYSCON.FLEXCAN1CLKSEL.sel, value: NO_CLOCK} +- {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} +- {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} +sources: +- {id: SCG.FIRC.outFreq, value: 144 MHz} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockFROHF144M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockFROHF144M configuration + ******************************************************************************/ +void BOARD_BootClockFROHF144M(void) +{ + /*!< Enable SCG clock */ + CLOCK_EnableClock(kCLOCK_Scg); + + CLOCK_SetupFROHFClocking(144000000U); /*!< Enable FRO HF(144MHz) output */ + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO_HF */ + + /*!< Set up dividers */ + CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 2U); /*!< Set AHBCLKDIV divider to value 2 */ + + /* Set SystemCoreClock variable */ + SystemCoreClock = BOARD_BOOTCLOCKFROHF144M_CORE_CLOCK; +} + +/******************************************************************************* + ******************** Configuration BOARD_BootClockPLL150M ********************* + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockPLL150M +called_from_default_init: true +outputs: +- {id: CLK_144M_clock.outFreq, value: 144 MHz} +- {id: CLK_48M_clock.outFreq, value: 48 MHz} +- {id: FRO_12M_clock.outFreq, value: 12 MHz} +- {id: FRO_HF_clock.outFreq, value: 48 MHz} +- {id: MAIN_clock.outFreq, value: 150 MHz} +- {id: PLL0_CLK_clock.outFreq, value: 150 MHz} +- {id: Slow_clock.outFreq, value: 37.5 MHz} +- {id: System_clock.outFreq, value: 150 MHz} +- {id: gdet_clock.outFreq, value: 48 MHz} +- {id: trng_clock.outFreq, value: 48 MHz} +settings: +- {id: PLL0_Mode, value: Normal} +- {id: RunPowerMode, value: OD} +- {id: SCGMode, value: PLL0} +- {id: SCG.PLL0M_MULT.scale, value: '50', locked: true} +- {id: SCG.PLL0SRCSEL.sel, value: SCG.FIRC_48M} +- {id: SCG.PLL0_NDIV.scale, value: '8', locked: true} +- {id: SCG.SCSSEL.sel, value: SCG.PLL0_CLK} +- {id: SYSCON.FLEXCAN0CLKSEL.sel, value: NO_CLOCK} +- {id: SYSCON.FLEXCAN1CLKSEL.sel, value: NO_CLOCK} +- {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} +- {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockPLL150M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockPLL150M configuration + ******************************************************************************/ +void BOARD_BootClockPLL150M(void) +{ + /*!< Enable SCG clock */ + CLOCK_EnableClock(kCLOCK_Scg); + + CLOCK_SetupFROHFClocking(48000000U); /*!< Enable FRO HF(48MHz) output */ + + /*!< Set up PLL0 */ + const pll_setup_t pll0Setup = { + .pllctrl = SCG_APLLCTRL_SOURCE(1U) | SCG_APLLCTRL_SELI(27U) | SCG_APLLCTRL_SELP(13U), + .pllndiv = SCG_APLLNDIV_NDIV(8U), + .pllpdiv = SCG_APLLPDIV_PDIV(1U), + .pllmdiv = SCG_APLLMDIV_MDIV(50U), + .pllRate = 150000000U + }; + CLOCK_SetPLL0Freq(&pll0Setup); /*!< Configure PLL0 to the desired values */ + CLOCK_SetPll0MonitorMode(kSCG_Pll0MonitorDisable); /* Pll0 Monitor is disabled */ + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + CLOCK_AttachClk(kPLL0_to_MAIN_CLK); /*!< Switch MAIN_CLK to PLL0 */ + + /*!< Set up dividers */ + CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U); /*!< Set AHBCLKDIV divider to value 1 */ + + /* Set SystemCoreClock variable */ + SystemCoreClock = BOARD_BOOTCLOCKPLL150M_CORE_CLOCK; +} + +/******************************************************************************* + ******************** Configuration BOARD_BootClockPLL100M ********************* + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockPLL100M +outputs: +- {id: CLK_144M_clock.outFreq, value: 144 MHz} +- {id: CLK_48M_clock.outFreq, value: 48 MHz} +- {id: CLK_IN_clock.outFreq, value: 24 MHz} +- {id: FRO_12M_clock.outFreq, value: 12 MHz} +- {id: MAIN_clock.outFreq, value: 100 MHz} +- {id: PLL1_CLK_clock.outFreq, value: 100 MHz} +- {id: Slow_clock.outFreq, value: 25 MHz} +- {id: System_clock.outFreq, value: 100 MHz} +- {id: gdet_clock.outFreq, value: 48 MHz} +- {id: trng_clock.outFreq, value: 48 MHz} +settings: +- {id: PLL1_Mode, value: Normal} +- {id: SCGMode, value: PLL1} +- {id: SCG.PLL1M_MULT.scale, value: '100', locked: true} +- {id: SCG.PLL1_NDIV.scale, value: '6', locked: true} +- {id: SCG.PLL1_PDIV.scale, value: '4', locked: true} +- {id: SCG.SCSSEL.sel, value: SCG.PLL1_CLK} +- {id: SCG_FIRCCSR_FIRCEN_CFG, value: Disabled} +- {id: SCG_SOSCCSR_SOSCEN_CFG, value: Enabled} +- {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} +- {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} +sources: +- {id: SCG.SOSC.outFreq, value: 24 MHz, enabled: true} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockPLL100M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockPLL100M configuration + ******************************************************************************/ +void BOARD_BootClockPLL100M(void) +{ + /*!< Enable SCG clock */ + CLOCK_EnableClock(kCLOCK_Scg); + + CLOCK_SetupExtClocking(24000000U); + CLOCK_SetSysOscMonitorMode(kSCG_SysOscMonitorDisable); /* System OSC Clock Monitor is disabled */ + + /*!< Set up PLL1 */ + const pll_setup_t pll1Setup = { + .pllctrl = SCG_SPLLCTRL_SOURCE(0U) | SCG_SPLLCTRL_SELI(53U) | SCG_SPLLCTRL_SELP(26U), + .pllndiv = SCG_SPLLNDIV_NDIV(6U), + .pllpdiv = SCG_SPLLPDIV_PDIV(2U), + .pllmdiv = SCG_SPLLMDIV_MDIV(100U), + .pllRate = 100000000U + }; + CLOCK_SetPLL1Freq(&pll1Setup); /*!< Configure PLL1 to the desired values */ + CLOCK_SetPll1MonitorMode(kSCG_Pll1MonitorDisable); /* Pll1 Monitor is disabled */ + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + CLOCK_AttachClk(kPLL1_to_MAIN_CLK); /*!< Switch MAIN_CLK to PLL1 */ + + /*!< Set up dividers */ + CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U); /*!< Set AHBCLKDIV divider to value 1 */ + + /* Set SystemCoreClock variable */ + SystemCoreClock = BOARD_BOOTCLOCKPLL100M_CORE_CLOCK; +} diff --git a/hw/bsp/mcx/boards/frdm-mcxn947/clock_config.h b/hw/bsp/mcx/boards/frdm-mcxn947/clock_config.h new file mode 100644 index 000000000..c238a0423 --- /dev/null +++ b/hw/bsp/mcx/boards/frdm-mcxn947/clock_config.h @@ -0,0 +1,177 @@ +/* + * Copyright 2022 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _CLOCK_CONFIG_H_ +#define _CLOCK_CONFIG_H_ + +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define BOARD_XTAL0_CLK_HZ 24000000U /*!< Board xtal frequency in Hz */ +#define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32K frequency in Hz */ + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes default configuration of clocks. + * + */ +void BOARD_InitBootClocks(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************** Configuration BOARD_BootClockFRO12M ********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockFRO12M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKFRO12M_CORE_CLOCK 12000000U /*!< Core clock frequency: 12000000Hz */ +#define BOARD_BOOTCLOCKFRO12M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ + + +/******************************************************************************* + * API for BOARD_BootClockFRO12M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockFRO12M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************* Configuration BOARD_BootClockFROHF48M ********************* + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockFROHF48M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKFROHF48M_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */ +#define BOARD_BOOTCLOCKFROHF48M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ + + +/******************************************************************************* + * API for BOARD_BootClockFROHF48M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockFROHF48M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************* Configuration BOARD_BootClockFROHF144M ******************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockFROHF144M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKFROHF144M_CORE_CLOCK 144000000U /*!< Core clock frequency: 144000000Hz */ +#define BOARD_BOOTCLOCKFROHF144M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ + + +/******************************************************************************* + * API for BOARD_BootClockFROHF144M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockFROHF144M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************** Configuration BOARD_BootClockPLL150M ********************* + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockPLL150M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKPLL150M_CORE_CLOCK 150000000U /*!< Core clock frequency: 150000000Hz */ +#define BOARD_BOOTCLOCKPLL150M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ + + +/******************************************************************************* + * API for BOARD_BootClockPLL150M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockPLL150M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************** Configuration BOARD_BootClockPLL100M ********************* + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockPLL100M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKPLL100M_CORE_CLOCK 100000000U /*!< Core clock frequency: 100000000Hz */ +#define BOARD_BOOTCLOCKPLL100M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ + + +/******************************************************************************* + * API for BOARD_BootClockPLL100M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockPLL100M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +#endif /* _CLOCK_CONFIG_H_ */ diff --git a/hw/bsp/mcx/boards/frdm-mcxn947/pin_mux.c b/hw/bsp/mcx/boards/frdm-mcxn947/pin_mux.c new file mode 100644 index 000000000..acc2f3e45 --- /dev/null +++ b/hw/bsp/mcx/boards/frdm-mcxn947/pin_mux.c @@ -0,0 +1,141 @@ +/* + * Copyright 2022 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Pins v12.0 +processor: MCXN947 +package_id: MCXN947VDF +mcu_data: ksdk2_0 +processor_version: 0.12.3 + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +#include "fsl_common.h" +#include "fsl_port.h" +#include "pin_mux.h" + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitBootPins + * Description : Calls initialization functions. + * + * END ****************************************************************************************************************/ +void BOARD_InitBootPins(void) +{ + BOARD_InitPins(); +} + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitPins: +- options: {callFromInitBoot: 'true', coreID: cm33_core0, enableClock: 'true'} +- pin_list: + - {pin_num: A1, peripheral: LPFlexcomm4, signal: LPFLEXCOMM_P0, pin_signal: PIO1_8/WUU0_IN10/LPTMR1_ALT3/TRACE_DATA0/FC4_P0/FC5_P4/CT_INP8/SCT0_OUT2/FLEXIO0_D16/PLU_OUT0/ENET0_TXD2/I3C1_SDA/TSI0_CH17/ADC1_A8, + slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable, pull_value: low, input_buffer: enable, + invert_input: normal} + - {pin_num: B1, peripheral: LPFlexcomm4, signal: LPFLEXCOMM_P1, pin_signal: PIO1_9/TRACE_DATA1/FC4_P1/FC5_P5/CT_INP9/SCT0_OUT3/FLEXIO0_D17/PLU_OUT1/ENET0_TXD3/I3C1_SCL/TSI0_CH18/ADC1_A9, + slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable, input_buffer: enable, invert_input: normal} + - {pin_num: F14, peripheral: GPIO3, signal: 'GPIO, 4', pin_signal: PIO3_4/FC7_P2/CT_INP18/PWM0_X2/FLEXIO0_D12/SIM1_CLK, slew_rate: fast, open_drain: disable, drive_strength: low, + pull_select: down, pull_enable: disable, input_buffer: enable, invert_input: normal} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitPins(void) +{ + /* Enables the clock for PORT1: Enables clock */ + CLOCK_EnableClock(kCLOCK_Port1); + /* Enables the clock for PORT3: Enables clock */ + CLOCK_EnableClock(kCLOCK_Port3); + + const port_pin_config_t port1_8_pinA1_config = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Low internal pull resistor value is selected. */ + kPORT_LowPullResistor, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive input filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain output is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as FC4_P0 */ + kPORT_MuxAlt2, + /* Digital input enabled */ + kPORT_InputBufferEnable, + /* Digital input is not inverted */ + kPORT_InputNormal, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORT1_8 (pin A1) is configured as FC4_P0 */ + PORT_SetPinConfig(PORT1, 8U, &port1_8_pinA1_config); + + const port_pin_config_t port1_9_pinB1_config = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Low internal pull resistor value is selected. */ + kPORT_LowPullResistor, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive input filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain output is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as FC4_P1 */ + kPORT_MuxAlt2, + /* Digital input enabled */ + kPORT_InputBufferEnable, + /* Digital input is not inverted */ + kPORT_InputNormal, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORT1_9 (pin B1) is configured as FC4_P1 */ + PORT_SetPinConfig(PORT1, 9U, &port1_9_pinB1_config); + + const port_pin_config_t port3_4_pinF14_config = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Low internal pull resistor value is selected. */ + kPORT_LowPullResistor, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive input filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain output is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as PIO3_4 */ + kPORT_MuxAlt0, + /* Digital input enabled */ + kPORT_InputBufferEnable, + /* Digital input is not inverted */ + kPORT_InputNormal, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORT3_4 (pin F14) is configured as PIO3_4 */ + PORT_SetPinConfig(PORT3, 4U, &port3_4_pinF14_config); +} +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/mcx/boards/frdm-mcxn947/pin_mux.h b/hw/bsp/mcx/boards/frdm-mcxn947/pin_mux.h new file mode 100644 index 000000000..40968c275 --- /dev/null +++ b/hw/bsp/mcx/boards/frdm-mcxn947/pin_mux.h @@ -0,0 +1,51 @@ +/* + * Copyright 2022 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _PIN_MUX_H_ +#define _PIN_MUX_H_ + +/*! + * @addtogroup pin_mux + * @{ + */ + +/*********************************************************************************************************************** + * API + **********************************************************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Calls initialization functions. + * + */ +void BOARD_InitBootPins(void); + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitPins(void); + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ +#endif /* _PIN_MUX_H_ */ + +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ From b3ce3e25ebe08f6e0822bcd76006a65ab8bb02f0 Mon Sep 17 00:00:00 2001 From: Jerry Palacios Date: Tue, 23 Jan 2024 17:09:19 -0600 Subject: [PATCH 069/454] Led pin configurations changed from P3_4 to P0_10 --- hw/bsp/mcx/boards/frdm-mcxn947/pin_mux.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/hw/bsp/mcx/boards/frdm-mcxn947/pin_mux.c b/hw/bsp/mcx/boards/frdm-mcxn947/pin_mux.c index acc2f3e45..bf89b5329 100644 --- a/hw/bsp/mcx/boards/frdm-mcxn947/pin_mux.c +++ b/hw/bsp/mcx/boards/frdm-mcxn947/pin_mux.c @@ -62,10 +62,12 @@ BOARD_InitPins: * END ****************************************************************************************************************/ void BOARD_InitPins(void) { + /* Enables the clock for PORT0: Enables clock */ + CLOCK_EnableClock(kCLOCK_Port0); + /* Enables the clock for PORT1: Enables clock */ CLOCK_EnableClock(kCLOCK_Port1); - /* Enables the clock for PORT3: Enables clock */ - CLOCK_EnableClock(kCLOCK_Port3); + const port_pin_config_t port1_8_pinA1_config = {/* Internal pull-up/down resistor is disabled */ kPORT_PullDisable, @@ -113,7 +115,7 @@ void BOARD_InitPins(void) /* PORT1_9 (pin B1) is configured as FC4_P1 */ PORT_SetPinConfig(PORT1, 9U, &port1_9_pinB1_config); - const port_pin_config_t port3_4_pinF14_config = {/* Internal pull-up/down resistor is disabled */ + const port_pin_config_t port0_10_pinB12_config = {/* Internal pull-up/down resistor is disabled */ kPORT_PullDisable, /* Low internal pull resistor value is selected. */ kPORT_LowPullResistor, @@ -133,8 +135,8 @@ void BOARD_InitPins(void) kPORT_InputNormal, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; - /* PORT3_4 (pin F14) is configured as PIO3_4 */ - PORT_SetPinConfig(PORT3, 4U, &port3_4_pinF14_config); + /* PORT0_10 (pin B12) is configured as PIO0_10 */ + PORT_SetPinConfig(PORT0, 10U, &port0_10_pinB12_config); } /*********************************************************************************************************************** * EOF From fca0b44fa1e18fa8f968b9d4e090b1880b8b735e Mon Sep 17 00:00:00 2001 From: Jerry Palacios Date: Tue, 23 Jan 2024 17:10:21 -0600 Subject: [PATCH 070/454] Update pin_mux.c --- hw/bsp/mcx/boards/frdm-mcxn947/pin_mux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/bsp/mcx/boards/frdm-mcxn947/pin_mux.c b/hw/bsp/mcx/boards/frdm-mcxn947/pin_mux.c index bf89b5329..25e54e7e3 100644 --- a/hw/bsp/mcx/boards/frdm-mcxn947/pin_mux.c +++ b/hw/bsp/mcx/boards/frdm-mcxn947/pin_mux.c @@ -127,7 +127,7 @@ void BOARD_InitPins(void) kPORT_OpenDrainDisable, /* Low drive strength is configured */ kPORT_LowDriveStrength, - /* Pin is configured as PIO3_4 */ + /* Pin is configured as PIO0_10 */ kPORT_MuxAlt0, /* Digital input enabled */ kPORT_InputBufferEnable, From 2fadc06412c4e1076d911ffe82a69257a27d87fe Mon Sep 17 00:00:00 2001 From: Jerry Palacios Date: Tue, 23 Jan 2024 17:53:09 -0600 Subject: [PATCH 071/454] BOARD_InitPins pinlist modification BOARD_InitPins pinlist modification --- hw/bsp/mcx/boards/frdm-mcxn947/pin_mux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/bsp/mcx/boards/frdm-mcxn947/pin_mux.c b/hw/bsp/mcx/boards/frdm-mcxn947/pin_mux.c index 25e54e7e3..30a5ae456 100644 --- a/hw/bsp/mcx/boards/frdm-mcxn947/pin_mux.c +++ b/hw/bsp/mcx/boards/frdm-mcxn947/pin_mux.c @@ -48,7 +48,7 @@ BOARD_InitPins: invert_input: normal} - {pin_num: B1, peripheral: LPFlexcomm4, signal: LPFLEXCOMM_P1, pin_signal: PIO1_9/TRACE_DATA1/FC4_P1/FC5_P5/CT_INP9/SCT0_OUT3/FLEXIO0_D17/PLU_OUT1/ENET0_TXD3/I3C1_SCL/TSI0_CH18/ADC1_A9, slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable, input_buffer: enable, invert_input: normal} - - {pin_num: F14, peripheral: GPIO3, signal: 'GPIO, 4', pin_signal: PIO3_4/FC7_P2/CT_INP18/PWM0_X2/FLEXIO0_D12/SIM1_CLK, slew_rate: fast, open_drain: disable, drive_strength: low, + - {pin_num: B12, peripheral: GPIO0, signal: 'GPIO, 10', pin_signal: PIO0_12/ADC0_B10/FC0_P6/CT0O_MAT0/FLEXIO0_D2, slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, input_buffer: enable, invert_input: normal} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ From 17cd5e095255103696e1dde3c5dc7f06ef61274c Mon Sep 17 00:00:00 2001 From: Jerry Palacios Date: Tue, 23 Jan 2024 17:55:19 -0600 Subject: [PATCH 072/454] Bunny brain board created, but not modified yet Bunny brain board created, but not modified yet --- hw/bsp/mcx/boards/bunny-brain/board.cmake | 21 ++ hw/bsp/mcx/boards/bunny-brain/board.h | 66 ++++ hw/bsp/mcx/boards/bunny-brain/board.mk | 11 + hw/bsp/mcx/boards/bunny-brain/clock_config.c | 338 +++++++++++++++++++ hw/bsp/mcx/boards/bunny-brain/clock_config.h | 177 ++++++++++ hw/bsp/mcx/boards/bunny-brain/pin_mux.c | 141 ++++++++ hw/bsp/mcx/boards/bunny-brain/pin_mux.h | 51 +++ 7 files changed, 805 insertions(+) create mode 100644 hw/bsp/mcx/boards/bunny-brain/board.cmake create mode 100644 hw/bsp/mcx/boards/bunny-brain/board.h create mode 100644 hw/bsp/mcx/boards/bunny-brain/board.mk create mode 100644 hw/bsp/mcx/boards/bunny-brain/clock_config.c create mode 100644 hw/bsp/mcx/boards/bunny-brain/clock_config.h create mode 100644 hw/bsp/mcx/boards/bunny-brain/pin_mux.c create mode 100644 hw/bsp/mcx/boards/bunny-brain/pin_mux.h diff --git a/hw/bsp/mcx/boards/bunny-brain/board.cmake b/hw/bsp/mcx/boards/bunny-brain/board.cmake new file mode 100644 index 000000000..8c3280743 --- /dev/null +++ b/hw/bsp/mcx/boards/bunny-brain/board.cmake @@ -0,0 +1,21 @@ +set(MCU_VARIANT MCXN947) +set(MCU_CORE MCXN947_cm33_core0) + +set(JLINK_DEVICE MCXN947_M33_0) +set(PYOCD_TARGET MCXN947) +set(NXPLINK_DEVICE MCXN947:MCXN947) + +set(PORT 1) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + CPU_MCXN947VDF_cm33_core0 + BOARD_TUD_RHPORT=${PORT} + # port 0 is fullspeed, port 1 is highspeed + BOARD_TUD_MAX_SPEED=$ + ) + target_sources(${TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/clock_config.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/pin_mux.c + ) +endfunction() diff --git a/hw/bsp/mcx/boards/bunny-brain/board.h b/hw/bsp/mcx/boards/bunny-brain/board.h new file mode 100644 index 000000000..eae98bfa7 --- /dev/null +++ b/hw/bsp/mcx/boards/bunny-brain/board.h @@ -0,0 +1,66 @@ +/* + * 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 + +// LED +#define LED_GPIO GPIO3 +#define LED_CLK kCLOCK_Gpio3 +#define LED_PIN 4 // red +#define LED_STATE_ON 0 + +// WAKE button (Dummy, use unused pin +#define BUTTON_GPIO GPIO0 +#define BUTTON_CLK kCLOCK_Gpio0 +#define BUTTON_PIN 6 +#define BUTTON_STATE_ACTIVE 0 + +// UART +#define UART_DEV LPUART4 + +static inline void board_uart_init_clock(void) { + /* attach FRO 12M to FLEXCOMM4 */ + CLOCK_SetClkDiv(kCLOCK_DivFlexcom4Clk, 1u); + CLOCK_AttachClk(kFRO12M_to_FLEXCOMM4); + RESET_ClearPeripheralReset(kFC4_RST_SHIFT_RSTn); +} + +//#define UART_RX_PINMUX 0, 24, IOCON_PIO_DIG_FUNC1_EN +//#define UART_TX_PINMUX 0, 25, IOCON_PIO_DIG_FUNC1_EN + +// XTAL +#define XTAL0_CLK_HZ (24 * 1000 * 1000U) + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/hw/bsp/mcx/boards/bunny-brain/board.mk b/hw/bsp/mcx/boards/bunny-brain/board.mk new file mode 100644 index 000000000..aaad5e73e --- /dev/null +++ b/hw/bsp/mcx/boards/bunny-brain/board.mk @@ -0,0 +1,11 @@ +MCU_VARIANT = MCXN947 +MCU_CORE = MCXN947_cm33_core0 +PORT ?= 1 + +CFLAGS += -DCPU_MCXN947VDF_cm33_core0 + +JLINK_DEVICE = MCXN947_M33_0 +PYOCD_TARGET = MCXN947 + +# flash using pyocd +flash: flash-jlink diff --git a/hw/bsp/mcx/boards/bunny-brain/clock_config.c b/hw/bsp/mcx/boards/bunny-brain/clock_config.c new file mode 100644 index 000000000..37d2b4dfc --- /dev/null +++ b/hw/bsp/mcx/boards/bunny-brain/clock_config.c @@ -0,0 +1,338 @@ +/* + * Copyright 2022 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ +/* + * How to setup clock using clock driver functions: + * + * 1. Setup clock sources. + * + * 2. Set up wait states of the flash. + * + * 3. Set up all dividers. + * + * 4. Set up all selectors to provide selected clocks. + * + */ + +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Clocks v10.0 +processor: MCXN947 +package_id: MCXN947VDF +mcu_data: ksdk2_0 +processor_version: 0.12.3 +board: MCX-N9XX-EVK + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +#include "clock_config.h" +#include "fsl_clock.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ +/* System clock frequency. */ +// extern uint32_t SystemCoreClock; + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ +void BOARD_InitBootClocks(void) +{ + BOARD_BootClockPLL150M(); +} + +/******************************************************************************* + ******************** Configuration BOARD_BootClockFRO12M ********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockFRO12M +outputs: +- {id: CLK_144M_clock.outFreq, value: 144 MHz} +- {id: CLK_48M_clock.outFreq, value: 48 MHz} +- {id: FRO_12M_clock.outFreq, value: 12 MHz} +- {id: MAIN_clock.outFreq, value: 12 MHz} +- {id: Slow_clock.outFreq, value: 3 MHz} +- {id: System_clock.outFreq, value: 12 MHz} +- {id: gdet_clock.outFreq, value: 48 MHz} +- {id: trng_clock.outFreq, value: 48 MHz} +settings: +- {id: SCGMode, value: SIRC} +- {id: SCG.SCSSEL.sel, value: SCG.SIRC} +- {id: SCG_FIRCCSR_FIRCEN_CFG, value: Disabled} +- {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} +- {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockFRO12M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockFRO12M configuration + ******************************************************************************/ +void BOARD_BootClockFRO12M(void) +{ + /*!< Enable SCG clock */ + CLOCK_EnableClock(kCLOCK_Scg); + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO12M */ + + /*!< Set up dividers */ + CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U); /*!< Set AHBCLKDIV divider to value 1 */ + + /* Set SystemCoreClock variable */ + SystemCoreClock = BOARD_BOOTCLOCKFRO12M_CORE_CLOCK; +} + +/******************************************************************************* + ******************* Configuration BOARD_BootClockFROHF48M ********************* + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockFROHF48M +outputs: +- {id: CLK_144M_clock.outFreq, value: 144 MHz} +- {id: CLK_48M_clock.outFreq, value: 48 MHz} +- {id: FRO_12M_clock.outFreq, value: 12 MHz} +- {id: FRO_HF_clock.outFreq, value: 48 MHz} +- {id: MAIN_clock.outFreq, value: 48 MHz} +- {id: Slow_clock.outFreq, value: 12 MHz} +- {id: System_clock.outFreq, value: 48 MHz} +- {id: gdet_clock.outFreq, value: 48 MHz} +- {id: trng_clock.outFreq, value: 48 MHz} +settings: +- {id: SYSCON.FLEXCAN0CLKSEL.sel, value: NO_CLOCK} +- {id: SYSCON.FLEXCAN1CLKSEL.sel, value: NO_CLOCK} +- {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} +- {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockFROHF48M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockFROHF48M configuration + ******************************************************************************/ +void BOARD_BootClockFROHF48M(void) +{ + /*!< Enable SCG clock */ + CLOCK_EnableClock(kCLOCK_Scg); + + CLOCK_SetupFROHFClocking(48000000U); /*!< Enable FRO HF(48MHz) output */ + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO_HF */ + + /*!< Set up dividers */ + CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U); /*!< Set AHBCLKDIV divider to value 1 */ + + /* Set SystemCoreClock variable */ + SystemCoreClock = BOARD_BOOTCLOCKFROHF48M_CORE_CLOCK; +} + +/******************************************************************************* + ******************* Configuration BOARD_BootClockFROHF144M ******************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockFROHF144M +outputs: +- {id: CLK_144M_clock.outFreq, value: 144 MHz} +- {id: CLK_48M_clock.outFreq, value: 48 MHz} +- {id: FRO_12M_clock.outFreq, value: 12 MHz} +- {id: FRO_HF_clock.outFreq, value: 144 MHz} +- {id: MAIN_clock.outFreq, value: 144 MHz} +- {id: Slow_clock.outFreq, value: 18 MHz} +- {id: System_clock.outFreq, value: 72 MHz} +- {id: gdet_clock.outFreq, value: 48 MHz} +- {id: trng_clock.outFreq, value: 48 MHz} +settings: +- {id: SYSCON.AHBCLKDIV.scale, value: '2', locked: true} +- {id: SYSCON.FLEXCAN0CLKSEL.sel, value: NO_CLOCK} +- {id: SYSCON.FLEXCAN1CLKSEL.sel, value: NO_CLOCK} +- {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} +- {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} +sources: +- {id: SCG.FIRC.outFreq, value: 144 MHz} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockFROHF144M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockFROHF144M configuration + ******************************************************************************/ +void BOARD_BootClockFROHF144M(void) +{ + /*!< Enable SCG clock */ + CLOCK_EnableClock(kCLOCK_Scg); + + CLOCK_SetupFROHFClocking(144000000U); /*!< Enable FRO HF(144MHz) output */ + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO_HF */ + + /*!< Set up dividers */ + CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 2U); /*!< Set AHBCLKDIV divider to value 2 */ + + /* Set SystemCoreClock variable */ + SystemCoreClock = BOARD_BOOTCLOCKFROHF144M_CORE_CLOCK; +} + +/******************************************************************************* + ******************** Configuration BOARD_BootClockPLL150M ********************* + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockPLL150M +called_from_default_init: true +outputs: +- {id: CLK_144M_clock.outFreq, value: 144 MHz} +- {id: CLK_48M_clock.outFreq, value: 48 MHz} +- {id: FRO_12M_clock.outFreq, value: 12 MHz} +- {id: FRO_HF_clock.outFreq, value: 48 MHz} +- {id: MAIN_clock.outFreq, value: 150 MHz} +- {id: PLL0_CLK_clock.outFreq, value: 150 MHz} +- {id: Slow_clock.outFreq, value: 37.5 MHz} +- {id: System_clock.outFreq, value: 150 MHz} +- {id: gdet_clock.outFreq, value: 48 MHz} +- {id: trng_clock.outFreq, value: 48 MHz} +settings: +- {id: PLL0_Mode, value: Normal} +- {id: RunPowerMode, value: OD} +- {id: SCGMode, value: PLL0} +- {id: SCG.PLL0M_MULT.scale, value: '50', locked: true} +- {id: SCG.PLL0SRCSEL.sel, value: SCG.FIRC_48M} +- {id: SCG.PLL0_NDIV.scale, value: '8', locked: true} +- {id: SCG.SCSSEL.sel, value: SCG.PLL0_CLK} +- {id: SYSCON.FLEXCAN0CLKSEL.sel, value: NO_CLOCK} +- {id: SYSCON.FLEXCAN1CLKSEL.sel, value: NO_CLOCK} +- {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} +- {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockPLL150M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockPLL150M configuration + ******************************************************************************/ +void BOARD_BootClockPLL150M(void) +{ + /*!< Enable SCG clock */ + CLOCK_EnableClock(kCLOCK_Scg); + + CLOCK_SetupFROHFClocking(48000000U); /*!< Enable FRO HF(48MHz) output */ + + /*!< Set up PLL0 */ + const pll_setup_t pll0Setup = { + .pllctrl = SCG_APLLCTRL_SOURCE(1U) | SCG_APLLCTRL_SELI(27U) | SCG_APLLCTRL_SELP(13U), + .pllndiv = SCG_APLLNDIV_NDIV(8U), + .pllpdiv = SCG_APLLPDIV_PDIV(1U), + .pllmdiv = SCG_APLLMDIV_MDIV(50U), + .pllRate = 150000000U + }; + CLOCK_SetPLL0Freq(&pll0Setup); /*!< Configure PLL0 to the desired values */ + CLOCK_SetPll0MonitorMode(kSCG_Pll0MonitorDisable); /* Pll0 Monitor is disabled */ + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + CLOCK_AttachClk(kPLL0_to_MAIN_CLK); /*!< Switch MAIN_CLK to PLL0 */ + + /*!< Set up dividers */ + CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U); /*!< Set AHBCLKDIV divider to value 1 */ + + /* Set SystemCoreClock variable */ + SystemCoreClock = BOARD_BOOTCLOCKPLL150M_CORE_CLOCK; +} + +/******************************************************************************* + ******************** Configuration BOARD_BootClockPLL100M ********************* + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockPLL100M +outputs: +- {id: CLK_144M_clock.outFreq, value: 144 MHz} +- {id: CLK_48M_clock.outFreq, value: 48 MHz} +- {id: CLK_IN_clock.outFreq, value: 24 MHz} +- {id: FRO_12M_clock.outFreq, value: 12 MHz} +- {id: MAIN_clock.outFreq, value: 100 MHz} +- {id: PLL1_CLK_clock.outFreq, value: 100 MHz} +- {id: Slow_clock.outFreq, value: 25 MHz} +- {id: System_clock.outFreq, value: 100 MHz} +- {id: gdet_clock.outFreq, value: 48 MHz} +- {id: trng_clock.outFreq, value: 48 MHz} +settings: +- {id: PLL1_Mode, value: Normal} +- {id: SCGMode, value: PLL1} +- {id: SCG.PLL1M_MULT.scale, value: '100', locked: true} +- {id: SCG.PLL1_NDIV.scale, value: '6', locked: true} +- {id: SCG.PLL1_PDIV.scale, value: '4', locked: true} +- {id: SCG.SCSSEL.sel, value: SCG.PLL1_CLK} +- {id: SCG_FIRCCSR_FIRCEN_CFG, value: Disabled} +- {id: SCG_SOSCCSR_SOSCEN_CFG, value: Enabled} +- {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} +- {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} +sources: +- {id: SCG.SOSC.outFreq, value: 24 MHz, enabled: true} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockPLL100M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockPLL100M configuration + ******************************************************************************/ +void BOARD_BootClockPLL100M(void) +{ + /*!< Enable SCG clock */ + CLOCK_EnableClock(kCLOCK_Scg); + + CLOCK_SetupExtClocking(24000000U); + CLOCK_SetSysOscMonitorMode(kSCG_SysOscMonitorDisable); /* System OSC Clock Monitor is disabled */ + + /*!< Set up PLL1 */ + const pll_setup_t pll1Setup = { + .pllctrl = SCG_SPLLCTRL_SOURCE(0U) | SCG_SPLLCTRL_SELI(53U) | SCG_SPLLCTRL_SELP(26U), + .pllndiv = SCG_SPLLNDIV_NDIV(6U), + .pllpdiv = SCG_SPLLPDIV_PDIV(2U), + .pllmdiv = SCG_SPLLMDIV_MDIV(100U), + .pllRate = 100000000U + }; + CLOCK_SetPLL1Freq(&pll1Setup); /*!< Configure PLL1 to the desired values */ + CLOCK_SetPll1MonitorMode(kSCG_Pll1MonitorDisable); /* Pll1 Monitor is disabled */ + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + CLOCK_AttachClk(kPLL1_to_MAIN_CLK); /*!< Switch MAIN_CLK to PLL1 */ + + /*!< Set up dividers */ + CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U); /*!< Set AHBCLKDIV divider to value 1 */ + + /* Set SystemCoreClock variable */ + SystemCoreClock = BOARD_BOOTCLOCKPLL100M_CORE_CLOCK; +} diff --git a/hw/bsp/mcx/boards/bunny-brain/clock_config.h b/hw/bsp/mcx/boards/bunny-brain/clock_config.h new file mode 100644 index 000000000..c238a0423 --- /dev/null +++ b/hw/bsp/mcx/boards/bunny-brain/clock_config.h @@ -0,0 +1,177 @@ +/* + * Copyright 2022 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _CLOCK_CONFIG_H_ +#define _CLOCK_CONFIG_H_ + +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define BOARD_XTAL0_CLK_HZ 24000000U /*!< Board xtal frequency in Hz */ +#define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32K frequency in Hz */ + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes default configuration of clocks. + * + */ +void BOARD_InitBootClocks(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************** Configuration BOARD_BootClockFRO12M ********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockFRO12M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKFRO12M_CORE_CLOCK 12000000U /*!< Core clock frequency: 12000000Hz */ +#define BOARD_BOOTCLOCKFRO12M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ + + +/******************************************************************************* + * API for BOARD_BootClockFRO12M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockFRO12M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************* Configuration BOARD_BootClockFROHF48M ********************* + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockFROHF48M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKFROHF48M_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */ +#define BOARD_BOOTCLOCKFROHF48M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ + + +/******************************************************************************* + * API for BOARD_BootClockFROHF48M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockFROHF48M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************* Configuration BOARD_BootClockFROHF144M ******************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockFROHF144M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKFROHF144M_CORE_CLOCK 144000000U /*!< Core clock frequency: 144000000Hz */ +#define BOARD_BOOTCLOCKFROHF144M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ + + +/******************************************************************************* + * API for BOARD_BootClockFROHF144M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockFROHF144M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************** Configuration BOARD_BootClockPLL150M ********************* + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockPLL150M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKPLL150M_CORE_CLOCK 150000000U /*!< Core clock frequency: 150000000Hz */ +#define BOARD_BOOTCLOCKPLL150M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ + + +/******************************************************************************* + * API for BOARD_BootClockPLL150M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockPLL150M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************** Configuration BOARD_BootClockPLL100M ********************* + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockPLL100M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKPLL100M_CORE_CLOCK 100000000U /*!< Core clock frequency: 100000000Hz */ +#define BOARD_BOOTCLOCKPLL100M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ + + +/******************************************************************************* + * API for BOARD_BootClockPLL100M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockPLL100M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +#endif /* _CLOCK_CONFIG_H_ */ diff --git a/hw/bsp/mcx/boards/bunny-brain/pin_mux.c b/hw/bsp/mcx/boards/bunny-brain/pin_mux.c new file mode 100644 index 000000000..acc2f3e45 --- /dev/null +++ b/hw/bsp/mcx/boards/bunny-brain/pin_mux.c @@ -0,0 +1,141 @@ +/* + * Copyright 2022 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Pins v12.0 +processor: MCXN947 +package_id: MCXN947VDF +mcu_data: ksdk2_0 +processor_version: 0.12.3 + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +#include "fsl_common.h" +#include "fsl_port.h" +#include "pin_mux.h" + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitBootPins + * Description : Calls initialization functions. + * + * END ****************************************************************************************************************/ +void BOARD_InitBootPins(void) +{ + BOARD_InitPins(); +} + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitPins: +- options: {callFromInitBoot: 'true', coreID: cm33_core0, enableClock: 'true'} +- pin_list: + - {pin_num: A1, peripheral: LPFlexcomm4, signal: LPFLEXCOMM_P0, pin_signal: PIO1_8/WUU0_IN10/LPTMR1_ALT3/TRACE_DATA0/FC4_P0/FC5_P4/CT_INP8/SCT0_OUT2/FLEXIO0_D16/PLU_OUT0/ENET0_TXD2/I3C1_SDA/TSI0_CH17/ADC1_A8, + slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable, pull_value: low, input_buffer: enable, + invert_input: normal} + - {pin_num: B1, peripheral: LPFlexcomm4, signal: LPFLEXCOMM_P1, pin_signal: PIO1_9/TRACE_DATA1/FC4_P1/FC5_P5/CT_INP9/SCT0_OUT3/FLEXIO0_D17/PLU_OUT1/ENET0_TXD3/I3C1_SCL/TSI0_CH18/ADC1_A9, + slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable, input_buffer: enable, invert_input: normal} + - {pin_num: F14, peripheral: GPIO3, signal: 'GPIO, 4', pin_signal: PIO3_4/FC7_P2/CT_INP18/PWM0_X2/FLEXIO0_D12/SIM1_CLK, slew_rate: fast, open_drain: disable, drive_strength: low, + pull_select: down, pull_enable: disable, input_buffer: enable, invert_input: normal} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitPins(void) +{ + /* Enables the clock for PORT1: Enables clock */ + CLOCK_EnableClock(kCLOCK_Port1); + /* Enables the clock for PORT3: Enables clock */ + CLOCK_EnableClock(kCLOCK_Port3); + + const port_pin_config_t port1_8_pinA1_config = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Low internal pull resistor value is selected. */ + kPORT_LowPullResistor, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive input filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain output is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as FC4_P0 */ + kPORT_MuxAlt2, + /* Digital input enabled */ + kPORT_InputBufferEnable, + /* Digital input is not inverted */ + kPORT_InputNormal, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORT1_8 (pin A1) is configured as FC4_P0 */ + PORT_SetPinConfig(PORT1, 8U, &port1_8_pinA1_config); + + const port_pin_config_t port1_9_pinB1_config = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Low internal pull resistor value is selected. */ + kPORT_LowPullResistor, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive input filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain output is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as FC4_P1 */ + kPORT_MuxAlt2, + /* Digital input enabled */ + kPORT_InputBufferEnable, + /* Digital input is not inverted */ + kPORT_InputNormal, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORT1_9 (pin B1) is configured as FC4_P1 */ + PORT_SetPinConfig(PORT1, 9U, &port1_9_pinB1_config); + + const port_pin_config_t port3_4_pinF14_config = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Low internal pull resistor value is selected. */ + kPORT_LowPullResistor, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive input filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain output is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as PIO3_4 */ + kPORT_MuxAlt0, + /* Digital input enabled */ + kPORT_InputBufferEnable, + /* Digital input is not inverted */ + kPORT_InputNormal, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORT3_4 (pin F14) is configured as PIO3_4 */ + PORT_SetPinConfig(PORT3, 4U, &port3_4_pinF14_config); +} +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/mcx/boards/bunny-brain/pin_mux.h b/hw/bsp/mcx/boards/bunny-brain/pin_mux.h new file mode 100644 index 000000000..40968c275 --- /dev/null +++ b/hw/bsp/mcx/boards/bunny-brain/pin_mux.h @@ -0,0 +1,51 @@ +/* + * Copyright 2022 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _PIN_MUX_H_ +#define _PIN_MUX_H_ + +/*! + * @addtogroup pin_mux + * @{ + */ + +/*********************************************************************************************************************** + * API + **********************************************************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Calls initialization functions. + * + */ +void BOARD_InitBootPins(void); + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitPins(void); + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ +#endif /* _PIN_MUX_H_ */ + +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ From 64f86ef8e744e72e27b529ddb3440420ee4e3cf0 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 24 Jan 2024 11:32:28 +0700 Subject: [PATCH 073/454] build workflow with hil-test when test/hil changes --- .github/workflows/build_esp.yml | 2 ++ .github/workflows/build_iar.yml | 2 ++ .github/workflows/cmake_arm.yml | 2 ++ 3 files changed, 6 insertions(+) diff --git a/.github/workflows/build_esp.yml b/.github/workflows/build_esp.yml index 33caa0edb..65ade7b03 100644 --- a/.github/workflows/build_esp.yml +++ b/.github/workflows/build_esp.yml @@ -8,6 +8,7 @@ on: - 'examples/**' - 'lib/**' - 'hw/**' + - 'test/hil/**' - '.github/workflows/build_esp.yml' pull_request: branches: [ master ] @@ -16,6 +17,7 @@ on: - 'examples/**' - 'lib/**' - 'hw/**' + - 'test/hil/**' - '.github/workflows/build_esp.yml' concurrency: diff --git a/.github/workflows/build_iar.yml b/.github/workflows/build_iar.yml index 9f2cc0351..a0a022ecc 100644 --- a/.github/workflows/build_iar.yml +++ b/.github/workflows/build_iar.yml @@ -9,6 +9,7 @@ on: - 'lib/**' - 'hw/**' - 'tools/get_deps.py' + - 'test/hil/**' - '.github/workflows/build_iar.yml' pull_request: branches: [ master ] @@ -18,6 +19,7 @@ on: - 'lib/**' - 'hw/**' - 'tools/get_deps.py' + - 'test/hil/**' - '.github/workflows/build_iar.yml' concurrency: diff --git a/.github/workflows/cmake_arm.yml b/.github/workflows/cmake_arm.yml index 8b87fef21..4ef2de4a6 100644 --- a/.github/workflows/cmake_arm.yml +++ b/.github/workflows/cmake_arm.yml @@ -8,6 +8,7 @@ on: - 'examples/**' - 'lib/**' - 'hw/**' + - 'test/hil/**' - 'tools/get_deps.py' - '.github/workflows/cmake_arm.yml' pull_request: @@ -17,6 +18,7 @@ on: - 'examples/**' - 'lib/**' - 'hw/**' + - 'test/hil/**' - 'tools/get_deps.py' - '.github/workflows/cmake_arm.yml' From 9d0df8ebc5f643ff0b3dd06da14d11b3c1107a21 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 24 Jan 2024 12:10:17 +0700 Subject: [PATCH 074/454] add message when flashing failed --- test/hil/hil_test.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index 544a4eb39..7f03ce43f 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -370,6 +370,7 @@ def main(config_file, board): 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() From de1266699dc804d1ac35254abd3d0dc54d81ad75 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 13 Jan 2024 00:10:24 +0700 Subject: [PATCH 075/454] clean up video example for readability --- examples/device/video_capture/src/images.h | 3 + examples/device/video_capture/src/main.c | 86 +++++----- .../device/video_capture/src/tusb_config.h | 2 +- .../video_capture/src/usb_descriptors.c | 150 ++++++------------ hw/bsp/family_support.cmake | 1 - 5 files changed, 96 insertions(+), 146 deletions(-) diff --git a/examples/device/video_capture/src/images.h b/examples/device/video_capture/src/images.h index 784e7754c..ac372cb16 100644 --- a/examples/device/video_capture/src/images.h +++ b/examples/device/video_capture/src/images.h @@ -1,4 +1,5 @@ #if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) +// uncopmressed frame static const unsigned char frame_buffer[128 * (96 + 1) * 2] = { /* 0 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, @@ -1650,8 +1651,10 @@ static const unsigned char frame_buffer[128 * (96 + 1) * 2] = { 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, }; + #else +// mpeg compressed data (not CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) #define color_bar_0_jpg_len 511 #define color_bar_1_jpg_len 512 #define color_bar_2_jpg_len 511 diff --git a/examples/device/video_capture/src/main.c b/examples/device/video_capture/src/main.c index 711d4710a..7b180dd6b 100644 --- a/examples/device/video_capture/src/main.c +++ b/examples/device/video_capture/src/main.c @@ -40,7 +40,7 @@ * - 1000 ms : device mounted * - 2500 ms : device is suspended */ -enum { +enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, @@ -52,8 +52,7 @@ void led_blinking_task(void); void video_task(void); /*------------- MAIN -------------*/ -int main(void) -{ +int main(void) { board_init(); // init device stack on configured roothub port @@ -63,8 +62,7 @@ int main(void) board_init_after_tusb(); } - while (1) - { + while (1) { tud_task(); // tinyusb device task led_blinking_task(); @@ -77,33 +75,28 @@ 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; } - //--------------------------------------------------------------------+ // USB Video //--------------------------------------------------------------------+ @@ -111,11 +104,12 @@ static unsigned frame_num = 0; static unsigned tx_busy = 0; static unsigned interval_ms = 1000 / FRAME_RATE; -/* YUY2 frame buffer */ #ifdef CFG_EXAMPLE_VIDEO_READONLY +// For mcus that does not have enough SRAM for frame buffer, we use fixed frame data. +// To further reduce the size, we use MJPEG format instead of YUY2. #include "images.h" -# if !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) +#if !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) static struct { uint32_t size; uint8_t const *buffer; @@ -129,29 +123,31 @@ static struct { {color_bar_6_jpg_len, color_bar_6_jpg}, {color_bar_7_jpg_len, color_bar_7_jpg}, }; -# endif +#endif #else + +// YUY2 frame buffer static uint8_t frame_buffer[FRAME_WIDTH * FRAME_HEIGHT * 16 / 8]; -static void fill_color_bar(uint8_t *buffer, unsigned start_position) -{ + +static void fill_color_bar(uint8_t* buffer, unsigned start_position) { /* EBU color bars * See also https://stackoverflow.com/questions/6939422 */ static uint8_t const bar_color[8][4] = { - /* Y, U, Y, V */ - { 235, 128, 235, 128}, /* 100% White */ - { 219, 16, 219, 138}, /* Yellow */ - { 188, 154, 188, 16}, /* Cyan */ - { 173, 42, 173, 26}, /* Green */ - { 78, 214, 78, 230}, /* Magenta */ - { 63, 102, 63, 240}, /* Red */ - { 32, 240, 32, 118}, /* Blue */ - { 16, 128, 16, 128}, /* Black */ + /* Y, U, Y, V */ + { 235, 128, 235, 128}, /* 100% White */ + { 219, 16, 219, 138}, /* Yellow */ + { 188, 154, 188, 16}, /* Cyan */ + { 173, 42, 173, 26}, /* Green */ + { 78, 214, 78, 230}, /* Magenta */ + { 63, 102, 63, 240}, /* Red */ + { 32, 240, 32, 118}, /* Blue */ + { 16, 128, 16, 128}, /* Black */ }; - uint8_t *p; + uint8_t* p; /* Generate the 1st line */ - uint8_t *end = &buffer[FRAME_WIDTH * 2]; + uint8_t* end = &buffer[FRAME_WIDTH * 2]; unsigned idx = (FRAME_WIDTH / 2 - 1) - (start_position % (FRAME_WIDTH / 2)); p = &buffer[idx * 4]; for (unsigned i = 0; i < 8; ++i) { @@ -163,6 +159,7 @@ static void fill_color_bar(uint8_t *buffer, unsigned start_position) } } } + /* Duplicate the 1st line to the others */ p = &buffer[FRAME_WIDTH * 2]; for (unsigned i = 1; i < FRAME_HEIGHT; ++i) { @@ -170,16 +167,16 @@ static void fill_color_bar(uint8_t *buffer, unsigned start_position) p += FRAME_WIDTH * 2; } } + #endif -void video_task(void) -{ +void video_task(void) { static unsigned start_ms = 0; static unsigned already_sent = 0; if (!tud_video_n_streaming(0, 0)) { - already_sent = 0; - frame_num = 0; + already_sent = 0; + frame_num = 0; return; } @@ -195,7 +192,7 @@ void video_task(void) # endif #else fill_color_bar(frame_buffer, frame_num); - tud_video_n_frame_xfer(0, 0, (void*)frame_buffer, FRAME_WIDTH * FRAME_HEIGHT * 16/8); + tud_video_n_frame_xfer(0, 0, (void*) frame_buffer, FRAME_WIDTH * FRAME_HEIGHT * 16 / 8); #endif } @@ -213,22 +210,22 @@ void video_task(void) # endif #else fill_color_bar(frame_buffer, frame_num); - tud_video_n_frame_xfer(0, 0, (void*)frame_buffer, FRAME_WIDTH * FRAME_HEIGHT * 16/8); + tud_video_n_frame_xfer(0, 0, (void*) frame_buffer, FRAME_WIDTH * FRAME_HEIGHT * 16 / 8); #endif } -void tud_video_frame_xfer_complete_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) -{ - (void)ctl_idx; (void)stm_idx; +void tud_video_frame_xfer_complete_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) { + (void) ctl_idx; + (void) stm_idx; tx_busy = 0; /* flip buffer */ ++frame_num; } int tud_video_commit_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, - video_probe_and_commit_control_t const *parameters) -{ - (void)ctl_idx; (void)stm_idx; + video_probe_and_commit_control_t const* parameters) { + (void) ctl_idx; + (void) stm_idx; /* convert unit to ms from 100 ns */ interval_ms = parameters->dwFrameInterval / 10000; return VIDEO_ERROR_NONE; @@ -237,13 +234,12 @@ int tud_video_commit_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, //--------------------------------------------------------------------+ // 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/video_capture/src/tusb_config.h b/examples/device/video_capture/src/tusb_config.h index 274bf2b9c..8440b47ef 100644 --- a/examples/device/video_capture/src/tusb_config.h +++ b/examples/device/video_capture/src/tusb_config.h @@ -101,7 +101,7 @@ #define CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE 256 // use bulk endpoint for streaming interface -#define CFG_TUD_VIDEO_STREAMING_BULK 0 +#define CFG_TUD_VIDEO_STREAMING_BULK 1 #ifdef __cplusplus } diff --git a/examples/device/video_capture/src/usb_descriptors.c b/examples/device/video_capture/src/usb_descriptors.c index 49919fc58..d38f158c8 100644 --- a/examples/device/video_capture/src/usb_descriptors.c +++ b/examples/device/video_capture/src/usb_descriptors.c @@ -43,8 +43,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, @@ -70,111 +69,70 @@ 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) -{ - return (uint8_t const *) &desc_device; +uint8_t const* tud_descriptor_device_cb(void) { + return (uint8_t const*) &desc_device; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ -#if defined(CFG_EXAMPLE_VIDEO_READONLY) && !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) -# if 1 == CFG_TUD_VIDEO_STREAMING_BULK -# define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_VIDEO_CAPTURE_DESC_MJPEG_BULK_LEN) -# else -# define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_VIDEO_CAPTURE_DESC_MJPEG_LEN) -# endif -#else -# if 1 == CFG_TUD_VIDEO_STREAMING_BULK -# define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_VIDEO_CAPTURE_DESC_UNCOMPR_BULK_LEN) -# else -# define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_VIDEO_CAPTURE_DESC_UNCOMPR_LEN) -# endif -#endif - +// Select appropriate endpoint number #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, 5 Bulk etc ... -#if 1 == CFG_TUD_VIDEO_STREAMING_BULK - #define EPNUM_VIDEO_IN 0x82 -#else - #define EPNUM_VIDEO_IN 0x83 -#endif - + #define EPNUM_VIDEO_IN (CFG_TUD_VIDEO_STREAMING_BULK ? 0x82 : 0x83) #elif TU_CHECK_MCU(OPT_MCU_NRF5X) // nRF5x ISO can only be endpoint 8 - #define EPNUM_VIDEO_IN 0x88 - + #define EPNUM_VIDEO_IN (CFG_TUD_VIDEO_STREAMING_BULK ? 0x81 : 0x88) #else #define EPNUM_VIDEO_IN 0x81 - #endif -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, 0, 500), - - // IAD for Video Control +// For mcus that does not have enough SRAM for frame buffer, we use fixed frame data. +// To further reduce the size, we use MJPEG format instead of YUY2. +// Select interface descriptor and length accordingly. #if defined(CFG_EXAMPLE_VIDEO_READONLY) && !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) -# if 1 == CFG_TUD_VIDEO_STREAMING_BULK - TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG_BULK(4, EPNUM_VIDEO_IN, - FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, - 64) -# else - TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG(4, EPNUM_VIDEO_IN, - FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, - CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE) -# endif + #if CFG_TUD_VIDEO_STREAMING_BULK + #define ITF_VIDEO_DESC(epsize) TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG_BULK(4, EPNUM_VIDEO_IN, FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, epsize) + #define ITF_VIDEO_LEN TUD_VIDEO_CAPTURE_DESC_MJPEG_BULK_LEN + #else + #define ITF_VIDEO_DESC(epsize) TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG(4, EPNUM_VIDEO_IN, FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, epsize) + #define ITF_VIDEO_LEN TUD_VIDEO_CAPTURE_DESC_MJPEG_LEN + #endif #else -# if 1 == CFG_TUD_VIDEO_STREAMING_BULK - TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR_BULK(4, EPNUM_VIDEO_IN, - FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, - 64) -# else - TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR(4, EPNUM_VIDEO_IN, - FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, - CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE) -# endif + #if CFG_TUD_VIDEO_STREAMING_BULK + #define ITF_VIDEO_DESC(epsize) TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR_BULK(4, EPNUM_VIDEO_IN, FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, epsize) + #define ITF_VIDEO_LEN TUD_VIDEO_CAPTURE_DESC_UNCOMPR_BULK_LEN + #else + #define ITF_VIDEO_DESC(epsize) TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR(4, EPNUM_VIDEO_IN, FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, epsize) + #define ITF_VIDEO_LEN TUD_VIDEO_CAPTURE_DESC_UNCOMPR_LEN + #endif #endif + +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + ITF_VIDEO_LEN) + +// full speed descriptor +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, 0, 500), + + // IAD for Video Control + ITF_VIDEO_DESC(CFG_TUD_VIDEO_STREAMING_BULK ? 64 : CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE) }; #if TUD_OPT_HIGH_SPEED // Per USB specs: high speed capable device must report device_qualifier and other_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, 0, 500), // IAD for Video Control -#if defined(CFG_EXAMPLE_VIDEO_READONLY) && !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) -# if 1 == CFG_TUD_VIDEO_STREAMING_BULK - TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG_BULK(4, EPNUM_VIDEO_IN, - FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, - 512) -# else - TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG(4, EPNUM_VIDEO_IN, - FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, - CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE) -# endif -#else -# if 1 == CFG_TUD_VIDEO_STREAMING_BULK - TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR_BULK(4, EPNUM_VIDEO_IN, - FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, - 512) -# else - TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR(4, EPNUM_VIDEO_IN, - FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, - CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE) -# endif -#endif + ITF_VIDEO_DESC(CFG_TUD_VIDEO_STREAMING_BULK ? 512 : CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE) }; // 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_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = USB_BCD, @@ -192,29 +150,24 @@ 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 return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_fs_configuration : desc_hs_configuration; } - #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) -{ +uint8_t const* tud_descriptor_configuration_cb(uint8_t index) { (void) index; // for multiple configurations #if TUD_OPT_HIGH_SPEED @@ -238,24 +191,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 UVC", // 4: UVC 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 UVC", // 4: UVC 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; @@ -269,17 +221,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/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index 539a776a6..ff3393cfd 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -211,7 +211,6 @@ function(family_configure_common TARGET RTOS) target_link_options(${TARGET} PUBLIC "LINKER:--map=$.map") endif() - # ETM Trace option if (TRACE_ETM STREQUAL "1") target_compile_definitions(${TARGET} PUBLIC TRACE_ETM) From 0b8b8af83dfac97caa7c41f9d5c8c1a3af1b9ac1 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 25 Jan 2024 17:25:48 +0700 Subject: [PATCH 076/454] minor update to video capture example --- examples/device/video_capture/src/main.c | 15 +- .../device/video_capture/src/tusb_config.h | 2 +- .../video_capture/src/usb_descriptors.h | 69 +++----- src/class/video/video_device.c | 6 +- src/common/tusb_types.h | 154 +++++++----------- 5 files changed, 92 insertions(+), 154 deletions(-) diff --git a/examples/device/video_capture/src/main.c b/examples/device/video_capture/src/main.c index 7b180dd6b..e63335e67 100644 --- a/examples/device/video_capture/src/main.c +++ b/examples/device/video_capture/src/main.c @@ -131,8 +131,7 @@ static struct { static uint8_t frame_buffer[FRAME_WIDTH * FRAME_HEIGHT * 16 / 8]; static void fill_color_bar(uint8_t* buffer, unsigned start_position) { - /* EBU color bars - * See also https://stackoverflow.com/questions/6939422 */ + /* EBU color bars: https://stackoverflow.com/questions/6939422 */ static uint8_t const bar_color[8][4] = { /* Y, U, Y, V */ { 235, 128, 235, 128}, /* 100% White */ @@ -184,12 +183,12 @@ void video_task(void) { already_sent = 1; start_ms = board_millis(); #ifdef CFG_EXAMPLE_VIDEO_READONLY -# if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) + #if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)&frame_buffer[(frame_num % (FRAME_WIDTH / 2)) * 4], FRAME_WIDTH * FRAME_HEIGHT * 16/8); -# else + #else tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)frames[frame_num % 8].buffer, frames[frame_num % 8].size); -# endif + #endif #else fill_color_bar(frame_buffer, frame_num); tud_video_n_frame_xfer(0, 0, (void*) frame_buffer, FRAME_WIDTH * FRAME_HEIGHT * 16 / 8); @@ -202,12 +201,12 @@ void video_task(void) { start_ms += interval_ms; #ifdef CFG_EXAMPLE_VIDEO_READONLY -# if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) + #if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)&frame_buffer[(frame_num % (FRAME_WIDTH / 2)) * 4], FRAME_WIDTH * FRAME_HEIGHT * 16/8); -# else + #else tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)frames[frame_num % 8].buffer, frames[frame_num % 8].size); -# endif + #endif #else fill_color_bar(frame_buffer, frame_num); tud_video_n_frame_xfer(0, 0, (void*) frame_buffer, FRAME_WIDTH * FRAME_HEIGHT * 16 / 8); diff --git a/examples/device/video_capture/src/tusb_config.h b/examples/device/video_capture/src/tusb_config.h index 8440b47ef..d563c6f5c 100644 --- a/examples/device/video_capture/src/tusb_config.h +++ b/examples/device/video_capture/src/tusb_config.h @@ -97,7 +97,7 @@ // The number of video streaming interfaces #define CFG_TUD_VIDEO_STREAMING 1 -// video streaming endpoint size +// video streaming endpoint buffer size #define CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE 256 // use bulk endpoint for streaming interface diff --git a/examples/device/video_capture/src/usb_descriptors.h b/examples/device/video_capture/src/usb_descriptors.h index b924c8dbe..fa3c1fbd2 100644 --- a/examples/device/video_capture/src/usb_descriptors.h +++ b/examples/device/video_capture/src/usb_descriptors.h @@ -126,23 +126,17 @@ enum { #define TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR(_stridx, _epin, _width, _height, _fps, _epsize) \ TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \ /* Video control 0 */ \ - TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ - TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \ - /* wTotalLength - bLength */ \ - TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \ - UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ - TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\ - /*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\ - /*wObjectiveFocalLength*/0, /*bmControls*/0), \ + TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ + /* Header: UVC 1.5, length of followed descs, clock (deprecated), streaming interfaces */ \ + TUD_VIDEO_DESC_CS_VC(0x0150, TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ + /* Camera Terminal: ID, bAssocTerminal, iTerminal, focal min, max, length, bmControl */ \ + TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0, 0, 0, 0, 0), \ TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \ /* Video stream alt. 0 */ \ TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 0, _stridx), \ /* Video stream header for without still image capture */ \ TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ - /*wTotalLength - bLength */\ - TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN\ - + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN\ - + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ + /*wTotalLength - bLength */ TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ /*bmaControls(1)*/0), \ @@ -163,23 +157,17 @@ enum { #define TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG(_stridx, _epin, _width, _height, _fps, _epsize) \ TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \ /* Video control 0 */ \ - TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ - TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \ - /* wTotalLength - bLength */ \ - TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \ - UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ - TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\ - /*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\ - /*wObjectiveFocalLength*/0, /*bmControls*/0), \ + TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ + /* Header: UVC 1.5, length of followed descs, clock (deprecated), streaming interfaces */ \ + TUD_VIDEO_DESC_CS_VC(0x0150, TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ + /* Camera Terminal: ID, bAssocTerminal, iTerminal, focal min, max, length, bmControl */ \ + TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0, 0, 0, 0, 0), \ TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \ /* Video stream alt. 0 */ \ TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 0, _stridx), \ /* Video stream header for without still image capture */ \ TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ - /*wTotalLength - bLength */\ - TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN\ - + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN\ - + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ + /*wTotalLength - bLength */ TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ /*bmaControls(1)*/0), \ @@ -202,22 +190,17 @@ enum { TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \ /* Video control 0 */ \ TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ - TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \ - /* wTotalLength - bLength */ \ - TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \ - UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ - TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\ - /*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\ - /*wObjectiveFocalLength*/0, /*bmControls*/0), \ + /* Header: UVC 1.5, length of followed descs, clock (deprecated), streaming interfaces */ \ + TUD_VIDEO_DESC_CS_VC(0x0150, TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ + /* Camera Terminal: ID, bAssocTerminal, iTerminal, focal min, max, length, bmControl */ \ + TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0, 0, 0, 0, 0), \ TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \ /* Video stream alt. 0 */ \ TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 1, _stridx), \ /* Video stream header for without still image capture */ \ TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ /*wTotalLength - bLength */\ - TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN\ - + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN\ - + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ + TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ /*bmaControls(1)*/0), \ @@ -235,23 +218,17 @@ enum { #define TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG_BULK(_stridx, _epin, _width, _height, _fps, _epsize) \ TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \ /* Video control 0 */ \ - TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ - TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \ - /* wTotalLength - bLength */ \ - TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \ - UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ - TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\ - /*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\ - /*wObjectiveFocalLength*/0, /*bmControls*/0), \ + TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ + /* Header: UVC 1.5, length of followed descs, clock (deprecated), streaming interfaces */ \ + TUD_VIDEO_DESC_CS_VC(0x0150, TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ + /* Camera Terminal: ID, bAssocTerminal, iTerminal, focal min, max, length, bmControl */ \ + TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0, 0, 0, 0, 0), \ TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \ /* Video stream alt. 0 */ \ TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 1, _stridx), \ /* Video stream header for without still image capture */ \ TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ - /*wTotalLength - bLength */\ - TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN\ - + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN\ - + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ + /*wTotalLength - bLength */ TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ /*bmaControls(1)*/0), \ diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index 3b29454a3..c16a45fcd 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -434,8 +434,9 @@ static bool _update_streaming_parameters(videod_streaming_interface_t const *stm uint_fast32_t interval_ms = interval / 10000; TU_ASSERT(interval_ms); uint_fast32_t payload_size = (frame_size + interval_ms - 1) / interval_ms + 2; - if (CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE < payload_size) + if (CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE < payload_size) { payload_size = CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE; + } param->dwMaxPayloadTransferSize = payload_size; return true; } @@ -577,8 +578,9 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * } else { payload_size = (frame_size + interval_ms - 1) / interval_ms + 2; } - if (CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE < payload_size) + if (CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE < payload_size) { payload_size = CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE; + } param->dwMaxPayloadTransferSize = payload_size; } return true; diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index fab680989..d4ef1fd09 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -44,43 +44,38 @@ *------------------------------------------------------------------*/ /// defined base on EHCI specs value for Endpoint Speed -typedef enum -{ +typedef enum { TUSB_SPEED_FULL = 0, TUSB_SPEED_LOW = 1, TUSB_SPEED_HIGH = 2, TUSB_SPEED_INVALID = 0xff, -}tusb_speed_t; +} tusb_speed_t; /// defined base on USB Specs Endpoint's bmAttributes -typedef enum -{ +typedef enum { TUSB_XFER_CONTROL = 0 , TUSB_XFER_ISOCHRONOUS , TUSB_XFER_BULK , TUSB_XFER_INTERRUPT -}tusb_xfer_type_t; +} tusb_xfer_type_t; -typedef enum -{ +typedef enum { TUSB_DIR_OUT = 0, TUSB_DIR_IN = 1, TUSB_DIR_IN_MASK = 0x80 -}tusb_dir_t; +} tusb_dir_t; -enum -{ +enum { TUSB_EPSIZE_BULK_FS = 64, - TUSB_EPSIZE_BULK_HS= 512, + TUSB_EPSIZE_BULK_HS = 512, TUSB_EPSIZE_ISO_FS_MAX = 1023, TUSB_EPSIZE_ISO_HS_MAX = 1024, }; -/// Isochronous End Point Attributes -typedef enum -{ +/// Isochronous Endpoint Attributes +typedef enum { TUSB_ISO_EP_ATT_NO_SYNC = 0x00, TUSB_ISO_EP_ATT_ASYNCHRONOUS = 0x04, TUSB_ISO_EP_ATT_ADAPTIVE = 0x08, @@ -88,11 +83,10 @@ typedef enum TUSB_ISO_EP_ATT_DATA = 0x00, ///< Data End Point TUSB_ISO_EP_ATT_EXPLICIT_FB = 0x10, ///< Feedback End Point TUSB_ISO_EP_ATT_IMPLICIT_FB = 0x20, ///< Data endpoint that also serves as an implicit feedback -}tusb_iso_ep_attribute_t; +} tusb_iso_ep_attribute_t; /// USB Descriptor Types -typedef enum -{ +typedef enum { TUSB_DESC_DEVICE = 0x01, TUSB_DESC_CONFIGURATION = 0x02, TUSB_DESC_STRING = 0x03, @@ -119,10 +113,9 @@ typedef enum TUSB_DESC_SUPERSPEED_ENDPOINT_COMPANION = 0x30, TUSB_DESC_SUPERSPEED_ISO_ENDPOINT_COMPANION = 0x31 -}tusb_desc_type_t; +} tusb_desc_type_t; -typedef enum -{ +typedef enum { TUSB_REQ_GET_STATUS = 0 , TUSB_REQ_CLEAR_FEATURE = 1 , TUSB_REQ_RESERVED = 2 , @@ -136,25 +129,22 @@ typedef enum TUSB_REQ_GET_INTERFACE = 10 , TUSB_REQ_SET_INTERFACE = 11 , TUSB_REQ_SYNCH_FRAME = 12 -}tusb_request_code_t; +} tusb_request_code_t; -typedef enum -{ +typedef enum { TUSB_REQ_FEATURE_EDPT_HALT = 0, TUSB_REQ_FEATURE_REMOTE_WAKEUP = 1, TUSB_REQ_FEATURE_TEST_MODE = 2 -}tusb_request_feature_selector_t; +} tusb_request_feature_selector_t; -typedef enum -{ +typedef enum { TUSB_REQ_TYPE_STANDARD = 0, TUSB_REQ_TYPE_CLASS, TUSB_REQ_TYPE_VENDOR, TUSB_REQ_TYPE_INVALID } tusb_request_type_t; -typedef enum -{ +typedef enum { TUSB_REQ_RCPT_DEVICE =0, TUSB_REQ_RCPT_INTERFACE, TUSB_REQ_RCPT_ENDPOINT, @@ -162,8 +152,7 @@ typedef enum } tusb_request_recipient_t; // https://www.usb.org/defined-class-codes -typedef enum -{ +typedef enum { TUSB_CLASS_UNSPECIFIED = 0 , TUSB_CLASS_AUDIO = 1 , TUSB_CLASS_CDC = 2 , @@ -187,26 +176,23 @@ typedef enum TUSB_CLASS_MISC = 0xEF , TUSB_CLASS_APPLICATION_SPECIFIC = 0xFE , TUSB_CLASS_VENDOR_SPECIFIC = 0xFF -}tusb_class_code_t; +} tusb_class_code_t; typedef enum { MISC_SUBCLASS_COMMON = 2 }misc_subclass_type_t; -typedef enum -{ +typedef enum { MISC_PROTOCOL_IAD = 1 -}misc_protocol_type_t; +} misc_protocol_type_t; -typedef enum -{ +typedef enum { APP_SUBCLASS_USBTMC = 0x03, APP_SUBCLASS_DFU_RUNTIME = 0x01 } app_subclass_type_t; -typedef enum -{ +typedef enum { DEVICE_CAPABILITY_WIRELESS_USB = 0x01, DEVICE_CAPABILITY_USB20_EXTENSION = 0x02, DEVICE_CAPABILITY_SUPERSPEED_USB = 0x03, @@ -223,7 +209,7 @@ typedef enum DEVICE_CAPABILITY_AUTHENTICATION = 0x0E, DEVICE_CAPABILITY_BILLBOARD_EX = 0x0F, DEVICE_CAPABILITY_CONFIGURATION_SUMMARY = 0x10 -}device_capability_type_t; +} device_capability_type_t; enum { TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP = TU_BIT(5), @@ -235,28 +221,25 @@ enum { //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ -typedef enum -{ +typedef enum { XFER_RESULT_SUCCESS = 0, XFER_RESULT_FAILED, XFER_RESULT_STALLED, XFER_RESULT_TIMEOUT, XFER_RESULT_INVALID -}xfer_result_t; +} xfer_result_t; -enum // TODO remove -{ +// TODO remove +enum { DESC_OFFSET_LEN = 0, DESC_OFFSET_TYPE = 1 }; -enum -{ +enum { INTERFACE_INVALID_NUMBER = 0xff }; -typedef enum -{ +typedef enum { MS_OS_20_SET_HEADER_DESCRIPTOR = 0x00, MS_OS_20_SUBSET_HEADER_CONFIGURATION = 0x01, MS_OS_20_SUBSET_HEADER_FUNCTION = 0x02, @@ -268,16 +251,14 @@ typedef enum MS_OS_20_FEATURE_VENDOR_REVISION = 0x08 } microsoft_os_20_type_t; -enum -{ +enum { CONTROL_STAGE_IDLE, CONTROL_STAGE_SETUP, CONTROL_STAGE_DATA, CONTROL_STAGE_ACK }; -enum -{ +enum { TUSB_INDEX_INVALID_8 = 0xFFu }; @@ -290,8 +271,7 @@ TU_ATTR_PACKED_BEGIN TU_ATTR_BIT_FIELD_ORDER_BEGIN /// USB Device Descriptor -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. uint8_t bDescriptorType ; ///< DEVICE Descriptor Type. uint16_t bcdUSB ; ///< BUSB Specification Release Number in Binary-Coded Decimal (i.e., 2.10 is 210H). This field identifies the release of the USB Specification with which the device and its descriptors are compliant. @@ -314,8 +294,7 @@ typedef struct TU_ATTR_PACKED TU_VERIFY_STATIC( sizeof(tusb_desc_device_t) == 18, "size is not correct"); // USB Binary Device Object Store (BOS) Descriptor -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes uint8_t bDescriptorType ; ///< CONFIGURATION Descriptor Type uint16_t wTotalLength ; ///< Total length of data returned for this descriptor @@ -325,8 +304,7 @@ typedef struct TU_ATTR_PACKED TU_VERIFY_STATIC( sizeof(tusb_desc_bos_t) == 5, "size is not correct"); /// USB Configuration Descriptor -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes uint8_t bDescriptorType ; ///< CONFIGURATION Descriptor Type uint16_t wTotalLength ; ///< Total length of data returned for this configuration. Includes the combined length of all descriptors (configuration, interface, endpoint, and class- or vendor-specific) returned for this configuration. @@ -341,8 +319,7 @@ typedef struct TU_ATTR_PACKED TU_VERIFY_STATIC( sizeof(tusb_desc_configuration_t) == 9, "size is not correct"); /// USB Interface Descriptor -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes uint8_t bDescriptorType ; ///< INTERFACE Descriptor Type @@ -358,8 +335,7 @@ typedef struct TU_ATTR_PACKED TU_VERIFY_STATIC( sizeof(tusb_desc_interface_t) == 9, "size is not correct"); /// USB Endpoint Descriptor -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { uint8_t bLength ; // Size of this descriptor in bytes uint8_t bDescriptorType ; // ENDPOINT Descriptor Type @@ -379,8 +355,7 @@ typedef struct TU_ATTR_PACKED TU_VERIFY_STATIC( sizeof(tusb_desc_endpoint_t) == 7, "size is not correct"); /// USB Other Speed Configuration Descriptor -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of descriptor uint8_t bDescriptorType ; ///< Other_speed_Configuration Type uint16_t wTotalLength ; ///< Total length of data returned @@ -393,8 +368,7 @@ typedef struct TU_ATTR_PACKED } tusb_desc_other_speed_t; /// USB Device Qualifier Descriptor -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of descriptor uint8_t bDescriptorType ; ///< Device Qualifier Type uint16_t bcdUSB ; ///< USB specification version number (e.g., 0200H for V2.00) @@ -411,8 +385,7 @@ typedef struct TU_ATTR_PACKED TU_VERIFY_STATIC( sizeof(tusb_desc_device_qualifier_t) == 10, "size is not correct"); /// USB Interface Association Descriptor (IAD ECN) -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of descriptor uint8_t bDescriptorType ; ///< Other_speed_Configuration Type @@ -427,16 +400,14 @@ typedef struct TU_ATTR_PACKED } tusb_desc_interface_assoc_t; // USB String Descriptor -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes uint8_t bDescriptorType ; ///< Descriptor Type uint16_t unicode_string[]; } tusb_desc_string_t; // USB Binary Device Object Store (BOS) -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType ; uint8_t bDevCapabilityType; @@ -445,9 +416,8 @@ typedef struct TU_ATTR_PACKED uint8_t CapabilityData[]; } tusb_desc_bos_platform_t; -// USB WebuSB URL Descriptor -typedef struct TU_ATTR_PACKED -{ +// USB WebUSB URL Descriptor +typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; uint8_t bScheme; @@ -455,8 +425,7 @@ typedef struct TU_ATTR_PACKED } tusb_desc_webusb_url_t; // DFU Functional Descriptor -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; @@ -481,7 +450,7 @@ typedef struct TU_ATTR_PACKED // //--------------------------------------------------------------------+ -typedef struct TU_ATTR_PACKED{ +typedef struct TU_ATTR_PACKED { union { struct TU_ATTR_PACKED { uint8_t recipient : 5; ///< Recipient type tusb_request_recipient_t. @@ -509,36 +478,30 @@ TU_ATTR_BIT_FIELD_ORDER_END //--------------------------------------------------------------------+ // Get direction from Endpoint address -TU_ATTR_ALWAYS_INLINE static inline tusb_dir_t tu_edpt_dir(uint8_t addr) -{ +TU_ATTR_ALWAYS_INLINE static inline tusb_dir_t tu_edpt_dir(uint8_t addr) { return (addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT; } // Get Endpoint number from address -TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_edpt_number(uint8_t addr) -{ +TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_edpt_number(uint8_t addr) { return (uint8_t)(addr & (~TUSB_DIR_IN_MASK)); } -TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_edpt_addr(uint8_t num, uint8_t dir) -{ +TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_edpt_addr(uint8_t num, uint8_t dir) { return (uint8_t)(num | (dir ? TUSB_DIR_IN_MASK : 0)); } -TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_edpt_packet_size(tusb_desc_endpoint_t const* desc_ep) -{ +TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_edpt_packet_size(tusb_desc_endpoint_t const* desc_ep) { return tu_le16toh(desc_ep->wMaxPacketSize) & TU_GENMASK(10, 0); } #if CFG_TUSB_DEBUG -TU_ATTR_ALWAYS_INLINE static inline const char *tu_edpt_dir_str(tusb_dir_t dir) -{ +TU_ATTR_ALWAYS_INLINE static inline const char *tu_edpt_dir_str(tusb_dir_t dir) { tu_static const char *str[] = {"out", "in"}; return str[dir]; } -TU_ATTR_ALWAYS_INLINE static inline const char *tu_edpt_type_str(tusb_xfer_type_t t) -{ +TU_ATTR_ALWAYS_INLINE static inline const char *tu_edpt_type_str(tusb_xfer_type_t t) { tu_static const char *str[] = {"control", "isochronous", "bulk", "interrupt"}; return str[t]; } @@ -549,21 +512,18 @@ TU_ATTR_ALWAYS_INLINE static inline const char *tu_edpt_type_str(tusb_xfer_type_ //--------------------------------------------------------------------+ // return next descriptor -TU_ATTR_ALWAYS_INLINE static inline uint8_t const * tu_desc_next(void const* desc) -{ +TU_ATTR_ALWAYS_INLINE static inline uint8_t const * tu_desc_next(void const* desc) { uint8_t const* desc8 = (uint8_t const*) desc; return desc8 + desc8[DESC_OFFSET_LEN]; } // get descriptor type -TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_type(void const* desc) -{ +TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_type(void const* desc) { return ((uint8_t const*) desc)[DESC_OFFSET_TYPE]; } // get descriptor length -TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_len(void const* desc) -{ +TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_len(void const* desc) { return ((uint8_t const*) desc)[DESC_OFFSET_LEN]; } From 14d44171b59fc273adcccc1464da6e6cfb2c1864 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 25 Jan 2024 19:13:11 +0700 Subject: [PATCH 077/454] bump up to actions/setup-python@v5 --- .github/workflows/build_aarch64.yml | 2 +- .github/workflows/build_arm.yml | 2 +- .github/workflows/build_esp.yml | 2 +- .github/workflows/build_msp430.yml | 2 +- .github/workflows/build_renesas.yml | 2 +- .github/workflows/build_riscv.yml | 2 +- .github/workflows/build_win_mac.yml | 2 +- .github/workflows/cmake_arm.yml | 2 +- .github/workflows/pre-commit.yml | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build_aarch64.yml b/.github/workflows/build_aarch64.yml index 40fc8d63a..e5dbf9494 100644 --- a/.github/workflows/build_aarch64.yml +++ b/.github/workflows/build_aarch64.yml @@ -36,7 +36,7 @@ jobs: - 'broadcom_64bit' steps: - name: Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.x' diff --git a/.github/workflows/build_arm.yml b/.github/workflows/build_arm.yml index 4127db5bf..9f3270c91 100644 --- a/.github/workflows/build_arm.yml +++ b/.github/workflows/build_arm.yml @@ -46,7 +46,7 @@ jobs: - 'tm4c123 xmc4000' steps: - name: Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.x' diff --git a/.github/workflows/build_esp.yml b/.github/workflows/build_esp.yml index 65ade7b03..315df255e 100644 --- a/.github/workflows/build_esp.yml +++ b/.github/workflows/build_esp.yml @@ -37,7 +37,7 @@ jobs: - 'espressif_s3_devkitc' steps: - name: Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.x' diff --git a/.github/workflows/build_msp430.yml b/.github/workflows/build_msp430.yml index 296dbb766..f913df913 100644 --- a/.github/workflows/build_msp430.yml +++ b/.github/workflows/build_msp430.yml @@ -36,7 +36,7 @@ jobs: steps: - name: Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.x' diff --git a/.github/workflows/build_renesas.yml b/.github/workflows/build_renesas.yml index 017a29eee..ec06c9426 100644 --- a/.github/workflows/build_renesas.yml +++ b/.github/workflows/build_renesas.yml @@ -35,7 +35,7 @@ jobs: - 'rx' steps: - name: Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.x' diff --git a/.github/workflows/build_riscv.yml b/.github/workflows/build_riscv.yml index e030bb77f..e891a3a51 100644 --- a/.github/workflows/build_riscv.yml +++ b/.github/workflows/build_riscv.yml @@ -37,7 +37,7 @@ jobs: - 'gd32vf103' steps: - name: Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.x' diff --git a/.github/workflows/build_win_mac.yml b/.github/workflows/build_win_mac.yml index 7fa1a6943..b33b5b593 100644 --- a/.github/workflows/build_win_mac.yml +++ b/.github/workflows/build_win_mac.yml @@ -35,7 +35,7 @@ jobs: steps: - name: Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.x' diff --git a/.github/workflows/cmake_arm.yml b/.github/workflows/cmake_arm.yml index 4ef2de4a6..f97645ad1 100644 --- a/.github/workflows/cmake_arm.yml +++ b/.github/workflows/cmake_arm.yml @@ -59,7 +59,7 @@ jobs: - 'stm32u5' steps: - name: Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.x' diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 2e9ae9264..e36259daa 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.x' From a7de4ac9b7a2dfb1fa44921fb0f41f249c8cdd5e Mon Sep 17 00:00:00 2001 From: YixingShen Date: Fri, 26 Jan 2024 02:37:15 +0800 Subject: [PATCH 078/454] Correct VIDEO_CS_VS_INTERFACE_FRAME_MJPEG to VIDEO_CS_ITF_VS_FRAME_MJPEG for #define TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_DISC --- src/class/video/video.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/class/video/video.h b/src/class/video/video.h index d9880c291..268e219e2 100644 --- a/src/class/video/video.h +++ b/src/class/video/video.h @@ -537,7 +537,7 @@ TU_VERIFY_STATIC( sizeof(video_probe_and_commit_control_t) == 48, "size is not c /* Motion-JPEG 3.1.1 Table 3-2 and 3-4 */ #define TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_DISC(_frmidx, _cap, _width, _height, _minbr, _maxbr, _maxfrmbufsz, _frminterval, ...) \ TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_DISC_LEN + (TU_ARGS_NUM(__VA_ARGS__)) * 4, \ - TUSB_DESC_CS_INTERFACE, VIDEO_CS_VS_INTERFACE_FRAME_MJPEG, \ + TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VS_FRAME_MJPEG, \ _frmidx, _cap, U16_TO_U8S_LE(_width), U16_TO_U8S_LE(_height), U32_TO_U8S_LE(_minbr), U32_TO_U8S_LE(_maxbr), \ U32_TO_U8S_LE(_maxfrmbufsz), U32_TO_U8S_LE(_frminterval), (TU_ARGS_NUM(__VA_ARGS__)), __VA_ARGS__ From 19130440ccd0db8649b2f4e6c7ccb2ee2eaeefac Mon Sep 17 00:00:00 2001 From: YixingShen Date: Fri, 26 Jan 2024 02:46:53 +0800 Subject: [PATCH 079/454] Revert "Merge branch 'master' of https://github.com/YixingShen/tinyusb" This reverts commit 611f9d948be47b96520e84773525b9b79d3c7189, reversing changes made to a7de4ac9b7a2dfb1fa44921fb0f41f249c8cdd5e. --- hw/bsp/stm32f1/family.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/hw/bsp/stm32f1/family.c b/hw/bsp/stm32f1/family.c index 0c1b362ab..e79f9cd78 100644 --- a/hw/bsp/stm32f1/family.c +++ b/hw/bsp/stm32f1/family.c @@ -57,6 +57,9 @@ void board_init(void) { __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); + // Enable UART Clock + UART_CLK_EN(); + #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); @@ -83,10 +86,7 @@ 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; @@ -105,7 +105,6 @@ void board_init(void) { .Init.OverSampling = UART_OVERSAMPLING_16 }; HAL_UART_Init(&UartHandle); -#endif // USB Pins // Configure USB DM and DP pins. From 4c9f462423338a812378924233eac55ce0e96fb8 Mon Sep 17 00:00:00 2001 From: YixingShen Date: Fri, 26 Jan 2024 09:09:18 +0800 Subject: [PATCH 080/454] add "set tx_busy 1" into video_capture's video_tas for "if (tx_busy) return" --- examples/device/video_capture/src/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/device/video_capture/src/main.c b/examples/device/video_capture/src/main.c index 711d4710a..759c06057 100644 --- a/examples/device/video_capture/src/main.c +++ b/examples/device/video_capture/src/main.c @@ -185,6 +185,7 @@ void video_task(void) if (!already_sent) { already_sent = 1; + tx_busy = 1; start_ms = board_millis(); #ifdef CFG_EXAMPLE_VIDEO_READONLY # if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) @@ -203,6 +204,7 @@ void video_task(void) if (cur - start_ms < interval_ms) return; // not enough time if (tx_busy) return; start_ms += interval_ms; + tx_busy = 1; #ifdef CFG_EXAMPLE_VIDEO_READONLY # if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) From b5cd673330fc87f2981ecf139b24940df5cb3cfe Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 26 Jan 2024 22:55:55 +0700 Subject: [PATCH 081/454] rename and add more video descriptors use struct to define uvc descriptor for video_capture since uvc is rather too complicated to use macro templates --- .../video_capture/src/usb_descriptors.c | 233 ++++++++++++++++-- .../video_capture/src/usb_descriptors.h | 4 +- src/class/video/video.h | 230 ++++++++++++----- src/class/video/video_device.c | 20 +- src/common/tusb_types.h | 3 +- 5 files changed, 392 insertions(+), 98 deletions(-) diff --git a/examples/device/video_capture/src/usb_descriptors.c b/examples/device/video_capture/src/usb_descriptors.c index d38f158c8..8e54d3afd 100644 --- a/examples/device/video_capture/src/usb_descriptors.c +++ b/examples/device/video_capture/src/usb_descriptors.c @@ -40,6 +40,26 @@ #define USB_VID 0xCafe #define USB_BCD 0x0200 +// String Descriptor Index +enum { + STRID_LANGID = 0, + STRID_MANUFACTURER, + STRID_PRODUCT, + STRID_SERIAL, + STRID_UVC_CONTROL, + STRID_UVC_STREAMING, +}; + +// 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 UVC Control", // 4: UVC Interface + "TinyUSB UVC Streaming", // 5: UVC Interface +}; + //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ @@ -60,9 +80,9 @@ tusb_desc_device_t const desc_device = { .idProduct = USB_PID, .bcdDevice = 0x0100, - .iManufacturer = 0x01, - .iProduct = 0x02, - .iSerialNumber = 0x03, + .iManufacturer = STRID_MANUFACTURER, + .iProduct = STRID_PRODUCT, + .iSerialNumber = STRID_SERIAL, .bNumConfigurations = 0x01 }; @@ -164,6 +184,193 @@ uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index) { } #endif // highspeed +typedef struct TU_ATTR_PACKED { + tusb_desc_interface_t itf; + tusb_desc_video_control_header_1itf_t header; + tusb_desc_video_control_camera_terminal_t camera_terminal; + tusb_desc_video_control_output_terminal_t output_terminal; +} uvc_control_desc_t; + +/* Windows support YUY2 and NV12 + * https://docs.microsoft.com/en-us/windows-hardware/drivers/stream/usb-video-class-driver-overview */ + +typedef struct TU_ATTR_PACKED { + tusb_desc_interface_t itf; + tusb_desc_video_streaming_input_header_1byte_t header; + tusb_desc_video_format_uncompressed_t format; + tusb_desc_video_frame_uncompressed_continuous_t frame; + tusb_desc_video_streaming_color_matching_t color; + tusb_desc_endpoint_t ep; +} uvc_streaming_desc_t; + +typedef struct TU_ATTR_PACKED { + tusb_desc_configuration_t config; + tusb_desc_interface_assoc_t iad; + uvc_control_desc_t video_control; + uvc_streaming_desc_t video_streaming; +} uvc_cfg_desc_t; + +const uvc_cfg_desc_t config_desc = { + .config = { + .bLength = sizeof(tusb_desc_configuration_t), + .bDescriptorType = TUSB_DESC_CONFIGURATION, + + .wTotalLength = sizeof(uvc_cfg_desc_t), + .bNumInterfaces = ITF_NUM_TOTAL, + .bConfigurationValue = 1, + .iConfiguration = 0, + .bmAttributes = TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, + .bMaxPower = 100 / 2 + }, + .iad = { + .bLength = sizeof(tusb_desc_interface_assoc_t), + .bDescriptorType = TUSB_DESC_INTERFACE_ASSOCIATION, + + .bFirstInterface = ITF_NUM_VIDEO_CONTROL, + .bInterfaceCount = 2, + .bFunctionClass = TUSB_CLASS_VIDEO, + .bFunctionSubClass = VIDEO_SUBCLASS_INTERFACE_COLLECTION, + .bFunctionProtocol = VIDEO_ITF_PROTOCOL_UNDEFINED, + .iFunction = 0 + }, + + .video_control = { + .itf = { + .bLength = sizeof(tusb_desc_interface_t), + .bDescriptorType = TUSB_DESC_INTERFACE, + + .bInterfaceNumber = ITF_NUM_VIDEO_CONTROL, + .bAlternateSetting = 0, + .bNumEndpoints = 0, + .bInterfaceClass = TUSB_CLASS_VIDEO, + .bInterfaceSubClass = VIDEO_SUBCLASS_CONTROL, + .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, + .iInterface = STRID_UVC_CONTROL + }, + .header = { + .bLength = sizeof(tusb_desc_video_control_header_1itf_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VC_HEADER, + + .bcdUVC = VIDEO_BCD_1_50, + .wTotalLength = sizeof(uvc_control_desc_t) - sizeof(tusb_desc_interface_t), // CS VC descriptors only + .dwClockFrequency = UVC_CLOCK_FREQUENCY, + .bInCollection = 1, + .baInterfaceNr = { ITF_NUM_VIDEO_STREAMING } + }, + .camera_terminal = { + .bLength = sizeof(tusb_desc_video_control_camera_terminal_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VC_INPUT_TERMINAL, + + .bTerminalID = UVC_ENTITY_CAP_INPUT_TERMINAL, + .wTerminalType = VIDEO_ITT_CAMERA, + .bAssocTerminal = 0, + .iTerminal = 0, + .wObjectiveFocalLengthMin = 0, + .wObjectiveFocalLengthMax = 0, + .wOcularFocalLength = 0, + .bControlSize = 3, + .bmControls = { 0, 0, 0 } + }, + .output_terminal = { + .bLength = sizeof(tusb_desc_video_control_output_terminal_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VC_OUTPUT_TERMINAL, + + .bTerminalID = UVC_ENTITY_CAP_OUTPUT_TERMINAL, + .wTerminalType = VIDEO_TT_STREAMING, + .bAssocTerminal = 0, + .bSourceID = UVC_ENTITY_CAP_INPUT_TERMINAL, + .iTerminal = 0 + } + }, + + .video_streaming = { + .itf = { + .bLength = sizeof(tusb_desc_interface_t), + .bDescriptorType = TUSB_DESC_INTERFACE, + + .bInterfaceNumber = ITF_NUM_VIDEO_STREAMING, + .bAlternateSetting = 0, + .bNumEndpoints = 1, + .bInterfaceClass = TUSB_CLASS_VIDEO, + .bInterfaceSubClass = VIDEO_SUBCLASS_STREAMING, + .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, + .iInterface = STRID_UVC_STREAMING + }, + .header = { + .bLength = sizeof(tusb_desc_video_streaming_input_header_1byte_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_INPUT_HEADER, + + .bNumFormats = 1, + .wTotalLength = sizeof(uvc_streaming_desc_t) - sizeof(tusb_desc_interface_t) - sizeof(tusb_desc_endpoint_t), // CS VS descriptors only + .bEndpointAddress = EPNUM_VIDEO_IN, + .bmInfo = 0, + .bTerminalLink = UVC_ENTITY_CAP_OUTPUT_TERMINAL, + .bStillCaptureMethod = 0, + .bTriggerSupport = 0, + .bTriggerUsage = 0, + .bControlSize = 1, + .bmaControls = { 0 } + }, + .format = { + .bLength = sizeof(tusb_desc_video_format_uncompressed_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED, + + .bFormatIndex = 1, // 1-based index + .bNumFrameDescriptors = 1, + .guidFormat = { TUD_VIDEO_GUID_YUY2 }, + .bBitsPerPixel = 16, + .bDefaultFrameIndex = 1, + .bAspectRatioX = 0, + .bAspectRatioY = 0, + .bmInterlaceFlags = 0, + .bCopyProtect = 0 + }, + .frame = { + .bLength = sizeof(tusb_desc_video_frame_uncompressed_continuous_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED, + + .bFrameIndex = 1, // 1-based index + .bmCapabilities = 0, + .wWidth = FRAME_WIDTH, + .wHeight = FRAME_HEIGHT, + .dwMinBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * 1, + .dwMaxBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * FRAME_RATE, + .dwMaxVideoFrameBufferSize = FRAME_WIDTH * FRAME_HEIGHT * 16 / 8, + .dwDefaultFrameInterval = 10000000 / FRAME_RATE, + .bFrameIntervalType = 0, // continuous + .dwFrameInterval = { + 10000000 / FRAME_RATE, // min + 10000000, // max + 10000000 / FRAME_RATE // step + } + }, + .color = { + .bLength = sizeof(tusb_desc_video_streaming_color_matching_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_COLORFORMAT, + + .bColorPrimaries = VIDEO_COLOR_PRIMARIES_BT709, + .bTransferCharacteristics = VIDEO_COLOR_XFER_CH_BT709, + .bMatrixCoefficients = VIDEO_COLOR_COEF_SMPTE170M + }, + .ep = { + .bLength = sizeof(tusb_desc_endpoint_t), + .bDescriptorType = TUSB_DESC_ENDPOINT, + + .bEndpointAddress = EPNUM_VIDEO_IN, + .bmAttributes = { .xfer = TUSB_XFER_BULK }, + .wMaxPacketSize = CFG_TUD_VIDEO_STREAMING_BULK ? 64 : CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE, + .bInterval = 1 + } + } +}; + // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete @@ -174,7 +381,8 @@ uint8_t const* tud_descriptor_configuration_cb(uint8_t index) { // 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; +// return desc_fs_configuration; + return (uint8_t const*) &config_desc; #endif } @@ -182,23 +390,6 @@ 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) - "TinyUSB", // 1: Manufacturer - "TinyUSB Device", // 2: Product - NULL, // 3: Serials will use unique ID if possible - "TinyUSB UVC", // 4: UVC Interface -}; - static uint16_t _desc_str[32 + 1]; // Invoked when received GET STRING DESCRIPTOR request diff --git a/examples/device/video_capture/src/usb_descriptors.h b/examples/device/video_capture/src/usb_descriptors.h index fa3c1fbd2..fd908c9c2 100644 --- a/examples/device/video_capture/src/usb_descriptors.h +++ b/examples/device/video_capture/src/usb_descriptors.h @@ -210,7 +210,7 @@ enum { /* Video stream frame format */ \ TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT(/*bFrameIndex */1, 0, _width, _height, \ _width * _height * 16, _width * _height * 16 * _fps, \ - _width * _height * 16, \ + _width * _height * 16 / 8, \ (10000000/_fps), (10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \ TUD_VIDEO_DESC_EP_BULK(_epin, _epsize, 1) @@ -223,7 +223,7 @@ enum { TUD_VIDEO_DESC_CS_VC(0x0150, TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ /* Camera Terminal: ID, bAssocTerminal, iTerminal, focal min, max, length, bmControl */ \ TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0, 0, 0, 0, 0), \ - TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \ + TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, UVC_ENTITY_CAP_INPUT_TERMINAL, 0), \ /* Video stream alt. 0 */ \ TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 1, _stridx), \ /* Video stream header for without still image capture */ \ diff --git a/src/class/video/video.h b/src/class/video/video.h index d9880c291..162d4e4c4 100644 --- a/src/class/video/video.h +++ b/src/class/video/video.h @@ -29,6 +29,10 @@ #include "common/tusb_common.h" +enum { + VIDEO_BCD_1_50 = 0x0150, +}; + // Table 3-19 Color Matching Descriptor typedef enum { VIDEO_COLOR_PRIMARIES_UNDEFINED = 0x00, @@ -198,55 +202,98 @@ typedef enum { } video_terminal_type_t; //--------------------------------------------------------------------+ -// Descriptors +// Video Control (VC) Descriptors //--------------------------------------------------------------------+ /* 2.3.4.2 */ +#define tusb_desc_video_control_header_nitf_t(_nitf) \ + struct TU_ATTR_PACKED { \ + uint8_t bLength; \ + uint8_t bDescriptorType; \ + uint8_t bDescriptorSubType; \ + uint16_t bcdUVC; \ + uint16_t wTotalLength; \ + uint32_t dwClockFrequency; /* deprecated */ \ + uint8_t bInCollection; \ + uint8_t baInterfaceNr[_nitf]; \ + } + +typedef tusb_desc_video_control_header_nitf_t() tusb_desc_video_control_header_t; +typedef tusb_desc_video_control_header_nitf_t(1) tusb_desc_video_control_header_1itf_t; +typedef tusb_desc_video_control_header_nitf_t(2) tusb_desc_video_control_header_2itf_t; +typedef tusb_desc_video_control_header_nitf_t(3) tusb_desc_video_control_header_3itf_t; +typedef tusb_desc_video_control_header_nitf_t(4) tusb_desc_video_control_header_4itf_t; + typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; uint8_t bDescriptorSubType; - uint16_t bcdUVC; - uint16_t wTotalLength; - uint32_t dwClockFrequency; - uint8_t bInCollection; - uint8_t baInterfaceNr[]; -} tusb_desc_cs_video_ctl_itf_hdr_t; + uint8_t bTerminalID; + uint16_t wTerminalType; + uint8_t bAssocTerminal; + uint8_t iTerminal; +} tusb_desc_video_control_input_terminal_t; + +TU_VERIFY_STATIC(sizeof(tusb_desc_video_control_input_terminal_t) == 8, "size is not correct"); -/* 2.4.3.3 */ typedef struct TU_ATTR_PACKED { - uint8_t bHeaderLength; - union { - uint8_t bmHeaderInfo; - struct { - uint8_t FrameID: 1; - uint8_t EndOfFrame: 1; - uint8_t PresentationTime: 1; - uint8_t SourceClockReference: 1; - uint8_t PayloadSpecific: 1; - uint8_t StillImage: 1; - uint8_t Error: 1; - uint8_t EndOfHeader: 1; - }; - }; -} tusb_video_payload_header_t; + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bTerminalID; + uint16_t wTerminalType; + uint8_t bAssocTerminal; + uint8_t bSourceID; + uint8_t iTerminal; +} tusb_desc_video_control_output_terminal_t; + +TU_VERIFY_STATIC(sizeof(tusb_desc_video_control_output_terminal_t) == 9, "size is not correct"); + +typedef struct TU_ATTR_PACKED { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bTerminalID; + uint16_t wTerminalType; + uint8_t bAssocTerminal; + uint8_t iTerminal; + + uint16_t wObjectiveFocalLengthMin; + uint16_t wObjectiveFocalLengthMax; + uint16_t wOcularFocalLength; + uint8_t bControlSize; + uint8_t bmControls[3]; +} tusb_desc_video_control_camera_terminal_t; + +TU_VERIFY_STATIC(sizeof(tusb_desc_video_control_camera_terminal_t) == 18, "size is not correct"); + +//--------------------------------------------------------------------+ +// Video Streaming (VS) Descriptors +//--------------------------------------------------------------------+ /* 3.9.2.1 */ -typedef struct TU_ATTR_PACKED { - uint8_t bLength; - uint8_t bDescriptorType; - uint8_t bDescriptorSubType; - uint8_t bNumFormats; - uint16_t wTotalLength; - uint8_t bEndpointAddress; - uint8_t bmInfo; - uint8_t bTerminalLink; - uint8_t bStillCaptureMethod; - uint8_t bTriggerSupport; - uint8_t bTriggerUsage; - uint8_t bControlSize; - uint8_t bmaControls[]; -} tusb_desc_cs_video_stm_itf_in_hdr_t; +#define tusb_desc_video_streaming_input_header_nbyte_t(_nb) \ + struct TU_ATTR_PACKED { \ + uint8_t bLength; \ + uint8_t bDescriptorType; \ + uint8_t bDescriptorSubType; \ + uint8_t bNumFormats; /* Number of video payload Format descriptors for this interface */ \ + uint16_t wTotalLength; \ + uint8_t bEndpointAddress; \ + uint8_t bmInfo; /* Bit 0: dynamic format change supported */ \ + uint8_t bTerminalLink; \ + uint8_t bStillCaptureMethod; \ + uint8_t bTriggerSupport; /* Hardware trigger supported */ \ + uint8_t bTriggerUsage; \ + uint8_t bControlSize; /* sizeof of each control item */ \ + uint8_t bmaControls[_nb]; \ + } + +typedef tusb_desc_video_streaming_input_header_nbyte_t() tusb_desc_video_streaming_input_header_t; +typedef tusb_desc_video_streaming_input_header_nbyte_t(1) tusb_desc_video_streaming_input_header_1byte_t; +typedef tusb_desc_video_streaming_input_header_nbyte_t(2) tusb_desc_video_streaming_input_header_2byte_t; +typedef tusb_desc_video_streaming_input_header_nbyte_t(3) tusb_desc_video_streaming_input_header_3byte_t; +typedef tusb_desc_video_streaming_input_header_nbyte_t(4) tusb_desc_video_streaming_input_header_4byte_t; /* 3.9.2.2 */ typedef struct TU_ATTR_PACKED { @@ -259,7 +306,7 @@ typedef struct TU_ATTR_PACKED { uint8_t bTerminalLink; uint8_t bControlSize; uint8_t bmaControls[]; -} tusb_desc_cs_video_stm_itf_out_hdr_t; +} tusb_desc_video_streaming_output_header_t; typedef struct TU_ATTR_PACKED { uint8_t bLength; @@ -285,14 +332,33 @@ typedef struct TU_ATTR_PACKED { uint8_t bmaControls[]; } output; }; -} tusb_desc_cs_video_stm_itf_hdr_t; +} tusb_desc_video_streaming_inout_header_t; +// 3.9.2.6 Color Matching Descriptor +typedef struct TU_ATTR_PACKED { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bColorPrimaries; + uint8_t bTransferCharacteristics; + uint8_t bMatrixCoefficients; +} tusb_desc_video_streaming_color_matching_t; + +TU_VERIFY_STATIC(sizeof(tusb_desc_video_streaming_color_matching_t) == 6, "size is not correct"); + +//--------------------------------------------------------------------+ +// Format and Frame Descriptor +// Note: bFormatIndex & bFrameIndex are 1-based index +//--------------------------------------------------------------------+ + +//------------- Uncompressed -------------// +// Uncompressed payload specs: 3.1.1 format descriptor typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; uint8_t bDescriptorSubType; uint8_t bFormatIndex; - uint8_t bNumFrameDescriptors; + uint8_t bNumFrameDescriptors; // Number of frame descriptors for this format uint8_t guidFormat[16]; uint8_t bBitsPerPixel; uint8_t bDefaultFrameIndex; @@ -300,8 +366,39 @@ typedef struct TU_ATTR_PACKED { uint8_t bAspectRatioY; uint8_t bmInterlaceFlags; uint8_t bCopyProtect; -} tusb_desc_cs_video_fmt_uncompressed_t; +} tusb_desc_video_format_uncompressed_t; +// Uncompressed payload specs: 3.1.2 frame descriptor +#define tusb_desc_video_frame_uncompressed_nint_t(_nint) \ + struct TU_ATTR_PACKED { \ + uint8_t bLength; \ + uint8_t bDescriptorType; \ + uint8_t bDescriptorSubType; \ + uint8_t bFrameIndex; \ + uint8_t bmCapabilities; \ + uint16_t wWidth; \ + uint16_t wHeight; \ + uint32_t dwMinBitRate; \ + uint32_t dwMaxBitRate; \ + uint32_t dwMaxVideoFrameBufferSize; /* deprecated in 1.5 */ \ + uint32_t dwDefaultFrameInterval; \ + uint8_t bFrameIntervalType; \ + uint32_t dwFrameInterval[_nint]; \ + } + +typedef tusb_desc_video_frame_uncompressed_nint_t() tusb_desc_video_frame_uncompressed_t; +typedef tusb_desc_video_frame_uncompressed_nint_t(1) tusb_desc_video_frame_uncompressed_1int_t; +typedef tusb_desc_video_frame_uncompressed_nint_t(2) tusb_desc_video_frame_uncompressed_2int_t; +typedef tusb_desc_video_frame_uncompressed_nint_t(3) tusb_desc_video_frame_uncompressed_3int_t; +typedef tusb_desc_video_frame_uncompressed_nint_t(4) tusb_desc_video_frame_uncompressed_4int_t; + +// continuous = 3 intervals: min, max, step +typedef tusb_desc_video_frame_uncompressed_3int_t tusb_desc_video_frame_uncompressed_continuous_t; + +TU_VERIFY_STATIC(sizeof(tusb_desc_video_frame_uncompressed_continuous_t) == 38, "size is not correct"); + +//------------- MJPEG -------------// +// MJPEG payload specs: 3.1.1 formatt descriptor typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; @@ -314,8 +411,12 @@ typedef struct TU_ATTR_PACKED { uint8_t bAspectRatioY; uint8_t bmInterlaceFlags; uint8_t bCopyProtect; -} tusb_desc_cs_video_fmt_mjpeg_t; +} tusb_desc_video_format_mjpeg_t; +// MJPEG payload specs: 3.1.2 frame descriptor (same as uncompressed) +typedef tusb_desc_video_frame_uncompressed_t tusb_desc_video_frame_mjpeg_t; + +// DV payload specs: 3.1.1 typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; @@ -323,8 +424,9 @@ typedef struct TU_ATTR_PACKED { uint8_t bFormatIndex; uint32_t dwMaxVideoFrameBufferSize; /* deprecated */ uint8_t bFormatType; -} tusb_desc_cs_video_fmt_dv_t; +} tusb_desc_video_format_dv_t; +// Frame Based payload specs: 3.1.1 typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; @@ -339,25 +441,7 @@ typedef struct TU_ATTR_PACKED { uint8_t bmInterlaceFlags; uint8_t bCopyProtect; uint8_t bVaribaleSize; -} tusb_desc_cs_video_fmt_frame_based_t; - -typedef struct TU_ATTR_PACKED { - uint8_t bLength; - uint8_t bDescriptorType; - uint8_t bDescriptorSubType; - uint8_t bFrameIndex; - uint8_t bmCapabilities; - uint16_t wWidth; - uint16_t wHeight; - uint32_t dwMinBitRate; - uint32_t dwMaxBitRate; - uint32_t dwMaxVideoFrameBufferSize; /* deprecated */ - uint32_t dwDefaultFrameInterval; - uint8_t bFrameIntervalType; - uint32_t dwFrameInterval[]; -} tusb_desc_cs_video_frm_uncompressed_t; - -typedef tusb_desc_cs_video_frm_uncompressed_t tusb_desc_cs_video_frm_mjpeg_t; +} tusb_desc_video_format_framebased_t; typedef struct TU_ATTR_PACKED { uint8_t bLength; @@ -373,12 +457,30 @@ typedef struct TU_ATTR_PACKED { uint8_t bFrameIntervalType; uint32_t dwBytesPerLine; uint32_t dwFrameInterval[]; -} tusb_desc_cs_video_frm_frame_based_t; +} tusb_desc_video_frame_framebased_t; //--------------------------------------------------------------------+ // Requests //--------------------------------------------------------------------+ +/* 2.4.3.3 */ +typedef struct TU_ATTR_PACKED { + uint8_t bHeaderLength; + union { + uint8_t bmHeaderInfo; + struct { + uint8_t FrameID: 1; + uint8_t EndOfFrame: 1; + uint8_t PresentationTime: 1; + uint8_t SourceClockReference: 1; + uint8_t PayloadSpecific: 1; + uint8_t StillImage: 1; + uint8_t Error: 1; + uint8_t EndOfHeader: 1; + }; + }; +} tusb_video_payload_header_t; + /* 4.3.1.1 */ typedef struct TU_ATTR_PACKED { union { diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index c16a45fcd..1affd615e 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -50,17 +50,17 @@ typedef struct { tusb_desc_interface_t std; - tusb_desc_cs_video_ctl_itf_hdr_t ctl; + tusb_desc_video_control_header_t ctl; } tusb_desc_vc_itf_t; typedef struct { tusb_desc_interface_t std; - tusb_desc_cs_video_stm_itf_hdr_t stm; + tusb_desc_video_streaming_inout_header_t stm; } tusb_desc_vs_itf_t; typedef union { - tusb_desc_cs_video_ctl_itf_hdr_t ctl; - tusb_desc_cs_video_stm_itf_hdr_t stm; + tusb_desc_video_control_header_t ctl; + tusb_desc_video_streaming_inout_header_t stm; } tusb_desc_video_itf_hdr_t; typedef struct TU_ATTR_PACKED { @@ -78,9 +78,9 @@ typedef union { uint8_t bFormatIndex; uint8_t bNumFrameDescriptors; }; - tusb_desc_cs_video_fmt_uncompressed_t uncompressed; - tusb_desc_cs_video_fmt_mjpeg_t mjpeg; - tusb_desc_cs_video_fmt_frame_based_t frame_based; + tusb_desc_video_format_uncompressed_t uncompressed; + tusb_desc_video_format_mjpeg_t mjpeg; + tusb_desc_video_format_framebased_t frame_based; } tusb_desc_cs_video_fmt_t; typedef union { @@ -93,9 +93,9 @@ typedef union { uint16_t wWidth; uint16_t wHeight; }; - tusb_desc_cs_video_frm_uncompressed_t uncompressed; - tusb_desc_cs_video_frm_mjpeg_t mjpeg; - tusb_desc_cs_video_frm_frame_based_t frame_based; + tusb_desc_video_frame_uncompressed_t uncompressed; + tusb_desc_video_frame_mjpeg_t mjpeg; + tusb_desc_video_frame_framebased_t frame_based; } tusb_desc_cs_video_frm_t; /* video streaming interface */ diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index d4ef1fd09..2c5dce723 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -399,6 +399,8 @@ typedef struct TU_ATTR_PACKED { uint8_t iFunction ; ///< Index of the string descriptor describing the interface association. } tusb_desc_interface_assoc_t; +TU_VERIFY_STATIC( sizeof(tusb_desc_interface_assoc_t) == 8, "size is not correct"); + // USB String Descriptor typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes @@ -469,7 +471,6 @@ typedef struct TU_ATTR_PACKED { TU_VERIFY_STATIC( sizeof(tusb_control_request_t) == 8, "size is not correct"); - TU_ATTR_PACKED_END // End of all packed definitions TU_ATTR_BIT_FIELD_ORDER_END From 0daf8ec51b9513fbab9601fedb2150dda3927b05 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 26 Jan 2024 23:23:38 +0700 Subject: [PATCH 082/454] update example to work bulk mjpeg --- .../video_capture/src/usb_descriptors.c | 27 ++++++++++++++++++- src/class/video/video.h | 10 ++++++- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/examples/device/video_capture/src/usb_descriptors.c b/examples/device/video_capture/src/usb_descriptors.c index 8e54d3afd..90a6b27a2 100644 --- a/examples/device/video_capture/src/usb_descriptors.c +++ b/examples/device/video_capture/src/usb_descriptors.c @@ -109,6 +109,10 @@ uint8_t const* tud_descriptor_device_cb(void) { #define EPNUM_VIDEO_IN 0x81 #endif +#if defined(CFG_EXAMPLE_VIDEO_READONLY) && !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) + #define USE_MJPEG +#endif + // For mcus that does not have enough SRAM for frame buffer, we use fixed frame data. // To further reduce the size, we use MJPEG format instead of YUY2. // Select interface descriptor and length accordingly. @@ -197,8 +201,15 @@ typedef struct TU_ATTR_PACKED { typedef struct TU_ATTR_PACKED { tusb_desc_interface_t itf; tusb_desc_video_streaming_input_header_1byte_t header; + +#ifdef USE_MJPEG + tusb_desc_video_format_mjpeg_t format; + tusb_desc_video_frame_mjpeg_continuous_t frame; +#else tusb_desc_video_format_uncompressed_t format; tusb_desc_video_frame_uncompressed_continuous_t frame; +#endif + tusb_desc_video_streaming_color_matching_t color; tusb_desc_endpoint_t ep; } uvc_streaming_desc_t; @@ -316,14 +327,22 @@ const uvc_cfg_desc_t config_desc = { .bmaControls = { 0 } }, .format = { +#ifdef USE_MJPEG + .bLength = sizeof(tusb_desc_video_format_mjpeg_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_FORMAT_MJPEG, + .bFormatIndex = 1, // 1-based index + .bNumFrameDescriptors = 1, + .bmFlags = 0, +#else .bLength = sizeof(tusb_desc_video_format_uncompressed_t), .bDescriptorType = TUSB_DESC_CS_INTERFACE, .bDescriptorSubType = VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED, - .bFormatIndex = 1, // 1-based index .bNumFrameDescriptors = 1, .guidFormat = { TUD_VIDEO_GUID_YUY2 }, .bBitsPerPixel = 16, +#endif .bDefaultFrameIndex = 1, .bAspectRatioX = 0, .bAspectRatioY = 0, @@ -331,9 +350,15 @@ const uvc_cfg_desc_t config_desc = { .bCopyProtect = 0 }, .frame = { +#ifdef USE_MJPEG + .bLength = sizeof(tusb_desc_video_frame_mjpeg_continuous_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_FRAME_MJPEG, +#else .bLength = sizeof(tusb_desc_video_frame_uncompressed_continuous_t), .bDescriptorType = TUSB_DESC_CS_INTERFACE, .bDescriptorSubType = VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED, +#endif .bFrameIndex = 1, // 1-based index .bmCapabilities = 0, diff --git a/src/class/video/video.h b/src/class/video/video.h index 162d4e4c4..bed8eeecf 100644 --- a/src/class/video/video.h +++ b/src/class/video/video.h @@ -405,7 +405,7 @@ typedef struct TU_ATTR_PACKED { uint8_t bDescriptorSubType; uint8_t bFormatIndex; uint8_t bNumFrameDescriptors; - uint8_t bmFlags; + uint8_t bmFlags; // Bit 0: fixed size samples (1 = yes) uint8_t bDefaultFrameIndex; uint8_t bAspectRatioX; uint8_t bAspectRatioY; @@ -415,7 +415,15 @@ typedef struct TU_ATTR_PACKED { // MJPEG payload specs: 3.1.2 frame descriptor (same as uncompressed) typedef tusb_desc_video_frame_uncompressed_t tusb_desc_video_frame_mjpeg_t; +typedef tusb_desc_video_frame_uncompressed_1int_t tusb_desc_video_frame_mjpeg_1int_t; +typedef tusb_desc_video_frame_uncompressed_2int_t tusb_desc_video_frame_mjpeg_2int_t; +typedef tusb_desc_video_frame_uncompressed_3int_t tusb_desc_video_frame_mjpeg_3int_t; +typedef tusb_desc_video_frame_uncompressed_4int_t tusb_desc_video_frame_mjpeg_4int_t; +// continuous = 3 intervals: min, max, step +typedef tusb_desc_video_frame_mjpeg_3int_t tusb_desc_video_frame_mjpeg_continuous_t; + +//------------- DV -------------// // DV payload specs: 3.1.1 typedef struct TU_ATTR_PACKED { uint8_t bLength; From 2da8f763d751f658a4b7859ceb69e4247e1fbc5f Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 26 Jan 2024 23:50:58 +0700 Subject: [PATCH 083/454] update example to work with iso streaming --- .../video_capture/src/usb_descriptors.c | 46 +++++++++++++++---- .../video_capture/src/usb_descriptors.h | 2 +- 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/examples/device/video_capture/src/usb_descriptors.c b/examples/device/video_capture/src/usb_descriptors.c index 90a6b27a2..6f2a207fb 100644 --- a/examples/device/video_capture/src/usb_descriptors.c +++ b/examples/device/video_capture/src/usb_descriptors.c @@ -110,9 +110,13 @@ uint8_t const* tud_descriptor_device_cb(void) { #endif #if defined(CFG_EXAMPLE_VIDEO_READONLY) && !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) - #define USE_MJPEG + #define USE_MJPEG 1 +#else + #define USE_MJPEG 0 #endif +#define USE_ISO_STREAMING (!CFG_TUD_VIDEO_STREAMING_BULK) + // For mcus that does not have enough SRAM for frame buffer, we use fixed frame data. // To further reduce the size, we use MJPEG format instead of YUY2. // Select interface descriptor and length accordingly. @@ -202,7 +206,7 @@ typedef struct TU_ATTR_PACKED { tusb_desc_interface_t itf; tusb_desc_video_streaming_input_header_1byte_t header; -#ifdef USE_MJPEG +#if USE_MJPEG tusb_desc_video_format_mjpeg_t format; tusb_desc_video_frame_mjpeg_continuous_t frame; #else @@ -211,6 +215,12 @@ typedef struct TU_ATTR_PACKED { #endif tusb_desc_video_streaming_color_matching_t color; + +#if USE_ISO_STREAMING + // For ISO streaming, USB spec requires to alternate interface + tusb_desc_interface_t itf_alt; +#endif + tusb_desc_endpoint_t ep; } uvc_streaming_desc_t; @@ -230,7 +240,7 @@ const uvc_cfg_desc_t config_desc = { .bNumInterfaces = ITF_NUM_TOTAL, .bConfigurationValue = 1, .iConfiguration = 0, - .bmAttributes = TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, + .bmAttributes = TU_BIT(7), .bMaxPower = 100 / 2 }, .iad = { @@ -304,7 +314,7 @@ const uvc_cfg_desc_t config_desc = { .bInterfaceNumber = ITF_NUM_VIDEO_STREAMING, .bAlternateSetting = 0, - .bNumEndpoints = 1, + .bNumEndpoints = CFG_TUD_VIDEO_STREAMING_BULK, // bulk 1, iso 0 .bInterfaceClass = TUSB_CLASS_VIDEO, .bInterfaceSubClass = VIDEO_SUBCLASS_STREAMING, .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, @@ -316,7 +326,8 @@ const uvc_cfg_desc_t config_desc = { .bDescriptorSubType = VIDEO_CS_ITF_VS_INPUT_HEADER, .bNumFormats = 1, - .wTotalLength = sizeof(uvc_streaming_desc_t) - sizeof(tusb_desc_interface_t) - sizeof(tusb_desc_endpoint_t), // CS VS descriptors only + .wTotalLength = sizeof(uvc_streaming_desc_t) - sizeof(tusb_desc_interface_t) + - sizeof(tusb_desc_endpoint_t) - (USE_ISO_STREAMING ? sizeof(tusb_desc_interface_t) : 0) , // CS VS descriptors only .bEndpointAddress = EPNUM_VIDEO_IN, .bmInfo = 0, .bTerminalLink = UVC_ENTITY_CAP_OUTPUT_TERMINAL, @@ -327,7 +338,7 @@ const uvc_cfg_desc_t config_desc = { .bmaControls = { 0 } }, .format = { -#ifdef USE_MJPEG +#if USE_MJPEG .bLength = sizeof(tusb_desc_video_format_mjpeg_t), .bDescriptorType = TUSB_DESC_CS_INTERFACE, .bDescriptorSubType = VIDEO_CS_ITF_VS_FORMAT_MJPEG, @@ -350,7 +361,7 @@ const uvc_cfg_desc_t config_desc = { .bCopyProtect = 0 }, .frame = { -#ifdef USE_MJPEG +#if USE_MJPEG .bLength = sizeof(tusb_desc_video_frame_mjpeg_continuous_t), .bDescriptorType = TUSB_DESC_CS_INTERFACE, .bDescriptorSubType = VIDEO_CS_ITF_VS_FRAME_MJPEG, @@ -384,12 +395,31 @@ const uvc_cfg_desc_t config_desc = { .bTransferCharacteristics = VIDEO_COLOR_XFER_CH_BT709, .bMatrixCoefficients = VIDEO_COLOR_COEF_SMPTE170M }, + +#if USE_ISO_STREAMING + .itf_alt = { + .bLength = sizeof(tusb_desc_interface_t), + .bDescriptorType = TUSB_DESC_INTERFACE, + + .bInterfaceNumber = ITF_NUM_VIDEO_STREAMING, + .bAlternateSetting = 1, + .bNumEndpoints = 1, + .bInterfaceClass = TUSB_CLASS_VIDEO, + .bInterfaceSubClass = VIDEO_SUBCLASS_STREAMING, + .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, + .iInterface = STRID_UVC_STREAMING + }, +#endif + .ep = { .bLength = sizeof(tusb_desc_endpoint_t), .bDescriptorType = TUSB_DESC_ENDPOINT, .bEndpointAddress = EPNUM_VIDEO_IN, - .bmAttributes = { .xfer = TUSB_XFER_BULK }, + .bmAttributes = { + .xfer = CFG_TUD_VIDEO_STREAMING_BULK ? TUSB_XFER_BULK : TUSB_XFER_ISOCHRONOUS, + .sync = CFG_TUD_VIDEO_STREAMING_BULK ? 0 : 1 // asynchronous + }, .wMaxPacketSize = CFG_TUD_VIDEO_STREAMING_BULK ? 64 : CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE, .bInterval = 1 } diff --git a/examples/device/video_capture/src/usb_descriptors.h b/examples/device/video_capture/src/usb_descriptors.h index fd908c9c2..aba0d4b7a 100644 --- a/examples/device/video_capture/src/usb_descriptors.h +++ b/examples/device/video_capture/src/usb_descriptors.h @@ -146,7 +146,7 @@ enum { /* Video stream frame format */ \ TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT(/*bFrameIndex */1, 0, _width, _height, \ _width * _height * 16, _width * _height * 16 * _fps, \ - _width * _height * 16, \ + _width * _height * 16 / 8, \ (10000000/_fps), (10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \ /* VS alt 1 */\ From d52909ec5caae5413758eeb169e68c82c7588f3d Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 29 Jan 2024 18:02:57 +0700 Subject: [PATCH 084/454] remove the use of descriptor template for video capture example --- .../video_capture/src/usb_descriptors.c | 141 ++++++++---------- .../video_capture/src/usb_descriptors.h | 12 +- 2 files changed, 61 insertions(+), 92 deletions(-) diff --git a/examples/device/video_capture/src/usb_descriptors.c b/examples/device/video_capture/src/usb_descriptors.c index 6f2a207fb..17e11229d 100644 --- a/examples/device/video_capture/src/usb_descriptors.c +++ b/examples/device/video_capture/src/usb_descriptors.c @@ -97,6 +97,19 @@ uint8_t const* tud_descriptor_device_cb(void) { // Configuration Descriptor //--------------------------------------------------------------------+ +/* Time stamp base clock. It is a deprecated parameter. */ +#define UVC_CLOCK_FREQUENCY 27000000 + +/* video capture path */ +#define UVC_ENTITY_CAP_INPUT_TERMINAL 0x01 +#define UVC_ENTITY_CAP_OUTPUT_TERMINAL 0x02 + +enum { + ITF_NUM_VIDEO_CONTROL, + ITF_NUM_VIDEO_STREAMING, + ITF_NUM_TOTAL +}; + // Select appropriate endpoint number #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 @@ -117,81 +130,6 @@ uint8_t const* tud_descriptor_device_cb(void) { #define USE_ISO_STREAMING (!CFG_TUD_VIDEO_STREAMING_BULK) -// For mcus that does not have enough SRAM for frame buffer, we use fixed frame data. -// To further reduce the size, we use MJPEG format instead of YUY2. -// Select interface descriptor and length accordingly. -#if defined(CFG_EXAMPLE_VIDEO_READONLY) && !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) - #if CFG_TUD_VIDEO_STREAMING_BULK - #define ITF_VIDEO_DESC(epsize) TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG_BULK(4, EPNUM_VIDEO_IN, FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, epsize) - #define ITF_VIDEO_LEN TUD_VIDEO_CAPTURE_DESC_MJPEG_BULK_LEN - #else - #define ITF_VIDEO_DESC(epsize) TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG(4, EPNUM_VIDEO_IN, FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, epsize) - #define ITF_VIDEO_LEN TUD_VIDEO_CAPTURE_DESC_MJPEG_LEN - #endif -#else - #if CFG_TUD_VIDEO_STREAMING_BULK - #define ITF_VIDEO_DESC(epsize) TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR_BULK(4, EPNUM_VIDEO_IN, FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, epsize) - #define ITF_VIDEO_LEN TUD_VIDEO_CAPTURE_DESC_UNCOMPR_BULK_LEN - #else - #define ITF_VIDEO_DESC(epsize) TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR(4, EPNUM_VIDEO_IN, FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, epsize) - #define ITF_VIDEO_LEN TUD_VIDEO_CAPTURE_DESC_UNCOMPR_LEN - #endif -#endif - -#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + ITF_VIDEO_LEN) - -// full speed descriptor -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, 0, 500), - - // IAD for Video Control - ITF_VIDEO_DESC(CFG_TUD_VIDEO_STREAMING_BULK ? 64 : CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE) -}; - -#if TUD_OPT_HIGH_SPEED -// Per USB specs: high speed capable device must report device_qualifier and other_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, 0, 500), - - // IAD for Video Control - ITF_VIDEO_DESC(CFG_TUD_VIDEO_STREAMING_BULK ? 512 : CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE) -}; - -// 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_t), - .bDescriptorType = TUSB_DESC_DEVICE, - .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 - return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_fs_configuration : desc_hs_configuration; -} -#endif // highspeed - typedef struct TU_ATTR_PACKED { tusb_desc_interface_t itf; tusb_desc_video_control_header_1itf_t header; @@ -231,7 +169,7 @@ typedef struct TU_ATTR_PACKED { uvc_streaming_desc_t video_streaming; } uvc_cfg_desc_t; -const uvc_cfg_desc_t config_desc = { +const uvc_cfg_desc_t desc_fs_configuration = { .config = { .bLength = sizeof(tusb_desc_configuration_t), .bDescriptorType = TUSB_DESC_CONFIGURATION, @@ -370,7 +308,6 @@ const uvc_cfg_desc_t config_desc = { .bDescriptorType = TUSB_DESC_CS_INTERFACE, .bDescriptorSubType = VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED, #endif - .bFrameIndex = 1, // 1-based index .bmCapabilities = 0, .wWidth = FRAME_WIDTH, @@ -426,6 +363,42 @@ const uvc_cfg_desc_t config_desc = { } }; +#if TUD_OPT_HIGH_SPEED +uvc_cfg_desc_t desc_hs_configuration = desc_fs_configuration; + +// 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_t), + .bDescriptorType = TUSB_DESC_DEVICE, + .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 + return (uint8_t const*) ((tud_speed_get() == TUSB_SPEED_HIGH) ? &desc_fs_configuration : &desc_hs_configuration); +} +#endif // highspeed + // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete @@ -434,11 +407,17 @@ uint8_t const* tud_descriptor_configuration_cb(uint8_t index) { #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; - return (uint8_t const*) &config_desc; + if (tud_speed_get() == TUSB_SPEED_HIGH) { + // change endpoint bulk size to 512 if bulk streaming + if (CFG_TUD_VIDEO_STREAMING_BULK) { + desc_hs_configuration.video_streaming.ep.wMaxPacketSize = 512; + } + return (uint8_t const*) &desc_hs_configuration; + } else #endif + { + return (uint8_t const*) &desc_fs_configuration; + } } //--------------------------------------------------------------------+ diff --git a/examples/device/video_capture/src/usb_descriptors.h b/examples/device/video_capture/src/usb_descriptors.h index aba0d4b7a..12d41b2f3 100644 --- a/examples/device/video_capture/src/usb_descriptors.h +++ b/examples/device/video_capture/src/usb_descriptors.h @@ -27,21 +27,11 @@ #ifndef _USB_DESCRIPTORS_H_ #define _USB_DESCRIPTORS_H_ -/* Time stamp base clock. It is a deprecated parameter. */ -#define UVC_CLOCK_FREQUENCY 27000000 -/* video capture path */ -#define UVC_ENTITY_CAP_INPUT_TERMINAL 0x01 -#define UVC_ENTITY_CAP_OUTPUT_TERMINAL 0x02 - #define FRAME_WIDTH 128 #define FRAME_HEIGHT 96 #define FRAME_RATE 10 -enum { - ITF_NUM_VIDEO_CONTROL, - ITF_NUM_VIDEO_STREAMING, - ITF_NUM_TOTAL -}; +// NOTE: descriptor template is not used but leave here as reference #define TUD_VIDEO_CAPTURE_DESC_UNCOMPR_LEN (\ TUD_VIDEO_DESC_IAD_LEN\ From 82be2477e8201fe6ea61324b8995b79d1b4cab46 Mon Sep 17 00:00:00 2001 From: IngHK Date: Mon, 29 Jan 2024 12:04:00 +0100 Subject: [PATCH 085/454] fixed #2437 --- src/class/cdc/cdc_host.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 7adaa0c8c..36b5d4234 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -77,6 +77,8 @@ typedef struct { uint8_t rx_ff_buf[CFG_TUH_CDC_TX_BUFSIZE]; CFG_TUH_MEM_ALIGN uint8_t rx_ep_buf[CFG_TUH_CDC_TX_EPSIZE]; } stream; + + bool configured; } cdch_interface_t; CFG_TUH_MEM_SECTION @@ -257,6 +259,7 @@ static cdch_interface_t* make_new_itf(uint8_t daddr, tusb_desc_interface_t const p_cdc->bInterfaceSubClass = itf_desc->bInterfaceSubClass; p_cdc->bInterfaceProtocol = itf_desc->bInterfaceProtocol; p_cdc->line_state = 0; + p_cdc->configured = false; return p_cdc; } } @@ -305,7 +308,8 @@ bool tuh_cdc_itf_get_info(uint8_t idx, tuh_itf_info_t* info) { bool tuh_cdc_mounted(uint8_t idx) { cdch_interface_t* p_cdc = get_itf(idx); - return p_cdc != NULL; + TU_VERIFY(p_cdc); + return p_cdc->configured; } bool tuh_cdc_get_dtr(uint8_t idx) { @@ -747,6 +751,7 @@ bool cdch_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const *itf_d static void set_config_complete(cdch_interface_t * p_cdc, uint8_t idx, uint8_t itf_num) { TU_LOG_DRV("CDCh Set Configure complete\r\n"); + p_cdc->configured = true; if (tuh_cdc_mount_cb) tuh_cdc_mount_cb(idx); // Prepare for incoming data From 55950656cbee915662a9a33477ddd549489ffcf0 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 29 Jan 2024 23:23:06 +0700 Subject: [PATCH 086/454] add freertos build support for video_capture example --- .../device/video_capture/src/CMakeLists.txt | 4 + examples/device/video_capture/src/main.c | 131 ++++++++++++++++-- .../device/video_capture/src/tusb_config.h | 8 ++ .../video_capture/src/usb_descriptors.c | 29 +++- hw/bsp/board_api.h | 19 ++- src/class/video/video.h | 2 +- 6 files changed, 170 insertions(+), 23 deletions(-) create mode 100644 examples/device/video_capture/src/CMakeLists.txt diff --git a/examples/device/video_capture/src/CMakeLists.txt b/examples/device/video_capture/src/CMakeLists.txt new file mode 100644 index 000000000..cef2b46ee --- /dev/null +++ b/examples/device/video_capture/src/CMakeLists.txt @@ -0,0 +1,4 @@ +# This file is for ESP-IDF only +idf_component_register(SRCS "main.c" "usb_descriptors.c" + INCLUDE_DIRS "." + REQUIRES boards tinyusb_src) diff --git a/examples/device/video_capture/src/main.c b/examples/device/video_capture/src/main.c index e63335e67..091eb8d0c 100644 --- a/examples/device/video_capture/src/main.c +++ b/examples/device/video_capture/src/main.c @@ -48,13 +48,25 @@ enum { static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; -void led_blinking_task(void); -void video_task(void); +void led_blinking_task(void* param); +void usb_device_task(void *param); +void video_task(void* param); -/*------------- MAIN -------------*/ +#if CFG_TUSB_OS == OPT_OS_FREERTOS +void freertos_init_task(void); +#endif + + +//--------------------------------------------------------------------+ +// Main +//--------------------------------------------------------------------+ int main(void) { board_init(); + // If using FreeRTOS: create blinky, tinyusb device, video task +#if CFG_TUSB_OS == OPT_OS_FREERTOS + freertos_init_task(); +#else // init device stack on configured roothub port tud_init(BOARD_TUD_RHPORT); @@ -64,10 +76,10 @@ int main(void) { while (1) { tud_task(); // tinyusb device task - led_blinking_task(); - - video_task(); + led_blinking_task(NULL); + video_task(NULL); } +#endif } //--------------------------------------------------------------------+ @@ -169,7 +181,7 @@ static void fill_color_bar(uint8_t* buffer, unsigned start_position) { #endif -void video_task(void) { +void video_send_frame(void) { static unsigned start_ms = 0; static unsigned already_sent = 0; @@ -213,6 +225,21 @@ void video_task(void) { #endif } + +void video_task(void* param) { + (void) param; + + while(1) { + video_send_frame(); + + #if CFG_TUSB_OS == OPT_OS_FREERTOS + vTaskDelay(interval_ms / portTICK_PERIOD_MS); + #else + return; + #endif + } +} + void tud_video_frame_xfer_complete_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) { (void) ctl_idx; (void) stm_idx; @@ -231,16 +258,92 @@ int tud_video_commit_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, } //--------------------------------------------------------------------+ -// BLINKING TASK +// Blinking Task //--------------------------------------------------------------------+ -void led_blinking_task(void) { +void led_blinking_task(void* param) { + (void) param; 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; + while (1) { + #if CFG_TUSB_OS == OPT_OS_FREERTOS + vTaskDelay(blink_interval_ms / portTICK_PERIOD_MS); + #else + if (board_millis() - start_ms < blink_interval_ms) return; // not enough time + #endif - board_led_write(led_state); - led_state = 1 - led_state; // toggle + start_ms += blink_interval_ms; + board_led_write(led_state); + led_state = 1 - led_state; // toggle + } } + +//--------------------------------------------------------------------+ +// FreeRTOS +//--------------------------------------------------------------------+ +#if CFG_TUSB_OS == OPT_OS_FREERTOS + +#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) + #define USBD_STACK_SIZE 4096 + int main(void); + void app_main(void) { + main(); + } +#else + // Increase stack size when debug log is enabled + #define USBD_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1) +#endif + +// 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 video_stack[VIDEO_STACK_SIZE]; +StaticTask_t video_taskdef; +#endif + +// USB Device Driver task +// This top level thread process all usb events and invoke callbacks +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. + tud_init(BOARD_TUD_RHPORT); + + if (board_init_after_tusb) { + board_init_after_tusb(); + } + + // RTOS forever loop + while (1) { + // put this thread to waiting state until there is new events + tud_task(); + } +} + +void freertos_init_task(void) { + #if configSUPPORT_STATIC_ALLOCATION + xTaskCreateStatic(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, blinky_stack, &blinky_taskdef); + xTaskCreateStatic(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_device_stack, &usb_device_taskdef); + xTaskCreateStatic(video_task, "cdc", VIDEO_STACK_SIZE, NULL, configMAX_PRIORITIES - 2, video_stack, &video_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(video_task, "video", VIDEO_STACK_SZIE, NULL, configMAX_PRIORITIES - 2, NULL); + #endif + + // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3 + #if !TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) + vTaskStartScheduler(); + #endif +} +#endif diff --git a/examples/device/video_capture/src/tusb_config.h b/examples/device/video_capture/src/tusb_config.h index d563c6f5c..bdfc37d87 100644 --- a/examples/device/video_capture/src/tusb_config.h +++ b/examples/device/video_capture/src/tusb_config.h @@ -57,6 +57,11 @@ #define CFG_TUSB_OS OPT_OS_NONE #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 @@ -103,6 +108,9 @@ // use bulk endpoint for streaming interface #define CFG_TUD_VIDEO_STREAMING_BULK 1 +//#define CFG_EXAMPLE_VIDEO_READONLY +//#define CFG_EXAMPLE_VIDEO_DISABLE_MJPEG + #ifdef __cplusplus } #endif diff --git a/examples/device/video_capture/src/usb_descriptors.c b/examples/device/video_capture/src/usb_descriptors.c index 17e11229d..f308c75a7 100644 --- a/examples/device/video_capture/src/usb_descriptors.c +++ b/examples/device/video_capture/src/usb_descriptors.c @@ -364,7 +364,22 @@ const uvc_cfg_desc_t desc_fs_configuration = { }; #if TUD_OPT_HIGH_SPEED -uvc_cfg_desc_t desc_hs_configuration = desc_fs_configuration; +uvc_cfg_desc_t desc_hs_configuration; + +static uint8_t * get_hs_configuration_desc(void) { + static bool init = false; + + if (!init) { + desc_hs_configuration = desc_fs_configuration; + // change endpoint bulk size to 512 if bulk streaming + if (CFG_TUD_VIDEO_STREAMING_BULK) { + desc_hs_configuration.video_streaming.ep.wMaxPacketSize = 512; + } + } + init = true; + + return (uint8_t *) &desc_hs_configuration; +} // 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 = { @@ -395,7 +410,11 @@ uint8_t const* tud_descriptor_device_qualifier_cb(void) { 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 - return (uint8_t const*) ((tud_speed_get() == TUSB_SPEED_HIGH) ? &desc_fs_configuration : &desc_hs_configuration); + if (tud_speed_get() == TUSB_SPEED_HIGH) { + return (uint8_t const*) &desc_fs_configuration; + } else { + return get_hs_configuration_desc(); + } } #endif // highspeed @@ -408,11 +427,7 @@ uint8_t const* tud_descriptor_configuration_cb(uint8_t index) { #if TUD_OPT_HIGH_SPEED // Although we are highspeed, host may be fullspeed. if (tud_speed_get() == TUSB_SPEED_HIGH) { - // change endpoint bulk size to 512 if bulk streaming - if (CFG_TUD_VIDEO_STREAMING_BULK) { - desc_hs_configuration.video_streaming.ep.wMaxPacketSize = 512; - } - return (uint8_t const*) &desc_hs_configuration; + return get_hs_configuration_desc(); } else #endif { diff --git a/hw/bsp/board_api.h b/hw/bsp/board_api.h index 404509a28..0c8a35924 100644 --- a/hw/bsp/board_api.h +++ b/hw/bsp/board_api.h @@ -33,9 +33,26 @@ extern "C" { #include #include - #include "tusb.h" +#if CFG_TUSB_OS == OPT_OS_FREERTOS +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) + // 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" +#else + #include "FreeRTOS.h" + #include "semphr.h" + #include "queue.h" + #include "task.h" + #include "timers.h" +#endif +#endif + // Define the default baudrate #ifndef CFG_BOARD_UART_BAUDRATE #define CFG_BOARD_UART_BAUDRATE 115200 ///< Default baud rate diff --git a/src/class/video/video.h b/src/class/video/video.h index bed8eeecf..fb0d0af1d 100644 --- a/src/class/video/video.h +++ b/src/class/video/video.h @@ -398,7 +398,7 @@ typedef tusb_desc_video_frame_uncompressed_3int_t tusb_desc_video_frame_uncompre TU_VERIFY_STATIC(sizeof(tusb_desc_video_frame_uncompressed_continuous_t) == 38, "size is not correct"); //------------- MJPEG -------------// -// MJPEG payload specs: 3.1.1 formatt descriptor +// MJPEG payload specs: 3.1.1 format descriptor typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; From 073a7a5659f06ce623e1081ac5f5566408fba670 Mon Sep 17 00:00:00 2001 From: YixingShen Date: Tue, 30 Jan 2024 08:30:37 +0800 Subject: [PATCH 087/454] revert the change in the f1 family.c since it break compile with other f1 that does not use UART. --- hw/bsp/stm32f1/family.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/hw/bsp/stm32f1/family.c b/hw/bsp/stm32f1/family.c index e79f9cd78..0c1b362ab 100644 --- a/hw/bsp/stm32f1/family.c +++ b/hw/bsp/stm32f1/family.c @@ -57,9 +57,6 @@ void board_init(void) { __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); - // Enable UART Clock - UART_CLK_EN(); - #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); @@ -86,7 +83,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; @@ -105,6 +105,7 @@ void board_init(void) { .Init.OverSampling = UART_OVERSAMPLING_16 }; HAL_UART_Init(&UartHandle); +#endif // USB Pins // Configure USB DM and DP pins. From 00ba4e95acec64da4446fa89a40c3a2e38beed3c Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 30 Jan 2024 10:59:12 +0700 Subject: [PATCH 088/454] cdch: de-configure when closing, rename configured to mounted --- src/class/cdc/cdc_host.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 36b5d4234..4e0a9499f 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -53,12 +53,13 @@ typedef struct { uint8_t bInterfaceSubClass; uint8_t bInterfaceProtocol; - uint8_t serial_drid; // Serial Driver ID - cdc_acm_capability_t acm_capability; uint8_t ep_notif; + uint8_t serial_drid; // Serial Driver ID + bool mounted; // Enumeration is complete + cdc_acm_capability_t acm_capability; - uint8_t line_state; // DTR (bit0), RTS (bit1) TU_ATTR_ALIGNED(4) cdc_line_coding_t line_coding; // Baudrate, stop bits, parity, data width + uint8_t line_state; // DTR (bit0), RTS (bit1) #if CFG_TUH_CDC_FTDI || CFG_TUH_CDC_CP210X || CFG_TUH_CDC_CH34X cdc_line_coding_t requested_line_coding; @@ -77,8 +78,6 @@ typedef struct { uint8_t rx_ff_buf[CFG_TUH_CDC_TX_BUFSIZE]; CFG_TUH_MEM_ALIGN uint8_t rx_ep_buf[CFG_TUH_CDC_TX_EPSIZE]; } stream; - - bool configured; } cdch_interface_t; CFG_TUH_MEM_SECTION @@ -259,7 +258,6 @@ static cdch_interface_t* make_new_itf(uint8_t daddr, tusb_desc_interface_t const p_cdc->bInterfaceSubClass = itf_desc->bInterfaceSubClass; p_cdc->bInterfaceProtocol = itf_desc->bInterfaceProtocol; p_cdc->line_state = 0; - p_cdc->configured = false; return p_cdc; } } @@ -309,7 +307,7 @@ bool tuh_cdc_itf_get_info(uint8_t idx, tuh_itf_info_t* info) { bool tuh_cdc_mounted(uint8_t idx) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); - return p_cdc->configured; + return p_cdc->mounted; } bool tuh_cdc_get_dtr(uint8_t idx) { @@ -648,9 +646,9 @@ void cdch_close(uint8_t daddr) { // Invoke application callback if (tuh_cdc_umount_cb) tuh_cdc_umount_cb(idx); - //tu_memclr(p_cdc, sizeof(cdch_interface_t)); p_cdc->daddr = 0; p_cdc->bInterfaceNumber = 0; + p_cdc->mounted = false; tu_edpt_stream_close(&p_cdc->stream.tx); tu_edpt_stream_close(&p_cdc->stream.rx); } @@ -751,7 +749,7 @@ bool cdch_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const *itf_d static void set_config_complete(cdch_interface_t * p_cdc, uint8_t idx, uint8_t itf_num) { TU_LOG_DRV("CDCh Set Configure complete\r\n"); - p_cdc->configured = true; + p_cdc->mounted = true; if (tuh_cdc_mount_cb) tuh_cdc_mount_cb(idx); // Prepare for incoming data From f600a8a0fc263b764ea018f0d0912f8001dd3160 Mon Sep 17 00:00:00 2001 From: IngHK Date: Tue, 30 Jan 2024 10:33:55 +0100 Subject: [PATCH 089/454] fix tuh_hid_mounted() similar to #2437 --- src/class/hid/hid_host.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index db52b503f..709fa3dd8 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -50,6 +50,7 @@ typedef struct uint8_t itf_num; uint8_t ep_in; uint8_t ep_out; + bool mounted; // Enumeration is complete uint8_t itf_protocol; // None, Keyboard, Mouse uint8_t protocol_mode; // Boot (0) or Report protocol (1) @@ -139,7 +140,8 @@ uint8_t tuh_hid_itf_get_total_count(void) bool tuh_hid_mounted(uint8_t daddr, uint8_t idx) { hidh_interface_t* p_hid = get_hid_itf(daddr, idx); - return p_hid != NULL; + TU_VERIFY(p_hid); + return p_hid->mounted; } bool tuh_hid_itf_get_info(uint8_t daddr, uint8_t idx, tuh_itf_info_t* info) @@ -463,6 +465,7 @@ void hidh_close(uint8_t daddr) TU_LOG_DRV(" HIDh close addr = %u index = %u\r\n", daddr, i); if(tuh_hid_umount_cb) tuh_hid_umount_cb(daddr, i); p_hid->daddr = 0; + p_hid->mounted = false; } } } @@ -632,6 +635,7 @@ static void config_driver_mount_complete(uint8_t daddr, uint8_t idx, uint8_t con { hidh_interface_t* p_hid = get_hid_itf(daddr, idx); TU_VERIFY(p_hid, ); + p_hid->mounted = true; // enumeration is complete if (tuh_hid_mount_cb) tuh_hid_mount_cb(daddr, idx, desc_report, desc_len); From 82776aaca9f7a8ae1b627c42cd69a021b1b50fe3 Mon Sep 17 00:00:00 2001 From: mamiral Date: Wed, 31 Jan 2024 10:48:15 +0100 Subject: [PATCH 090/454] Update vendor_device.c fifo mutex config similar to cdc_device.c. --- src/class/vendor/vendor_device.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index 389a29696..a68cb2156 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -49,10 +49,8 @@ typedef struct uint8_t rx_ff_buf[CFG_TUD_VENDOR_RX_BUFSIZE]; uint8_t tx_ff_buf[CFG_TUD_VENDOR_TX_BUFSIZE]; -#if CFG_FIFO_MUTEX - osal_mutex_def_t rx_ff_mutex; - osal_mutex_def_t tx_ff_mutex; -#endif + OSAL_MUTEX_DEF(rx_ff_mutex); + OSAL_MUTEX_DEF(tx_ff_mutex); // Endpoint Transfer buffer CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_VENDOR_EPSIZE]; @@ -183,10 +181,8 @@ void vendord_init(void) tu_fifo_config(&p_itf->rx_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); -#if CFG_FIFO_MUTEX tu_fifo_config_mutex(&p_itf->rx_ff, NULL, osal_mutex_create(&p_itf->rx_ff_mutex)); tu_fifo_config_mutex(&p_itf->tx_ff, osal_mutex_create(&p_itf->tx_ff_mutex), NULL); -#endif } } From e63a2f5c58b111a5f990ad1b6a0260f09a248c53 Mon Sep 17 00:00:00 2001 From: IngHK Date: Wed, 31 Jan 2024 18:00:25 +0100 Subject: [PATCH 091/454] fix #2444 and other small things --- src/class/cdc/cdc_host.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 4e0a9499f..2fb37d835 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -1345,7 +1345,7 @@ static inline bool ch34x_control_in(cdch_interface_t* p_cdc, uint8_t request, ui complete_cb, user_data); } -static bool ch34x_write_reg(cdch_interface_t* p_cdc, uint16_t reg, uint16_t reg_value, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { +static inline bool ch34x_write_reg(cdch_interface_t* p_cdc, uint16_t reg, uint16_t reg_value, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return ch34x_control_out(p_cdc, CH34X_REQ_WRITE_REG, reg, reg_value, complete_cb, user_data); } @@ -1358,7 +1358,7 @@ static bool ch34x_write_reg(cdch_interface_t* p_cdc, uint16_t reg, uint16_t reg_ static bool ch34x_write_reg_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { uint16_t const div_ps = ch34x_get_divisor_prescaler(baudrate); - TU_VERIFY(div_ps != 0); + TU_VERIFY(div_ps); TU_ASSERT(ch34x_write_reg(p_cdc, CH34X_REG16_DIVISOR_PRESCALER, div_ps, complete_cb, user_data)); return true; @@ -1379,7 +1379,7 @@ static bool ch34x_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, ui p_cdc->requested_line_coding.data_bits = data_bits; uint8_t const lcr = ch34x_get_lcr(stop_bits, parity, data_bits); - TU_VERIFY(lcr != 0); + TU_VERIFY(lcr); TU_ASSERT (ch34x_control_out(p_cdc, CH34X_REQ_WRITE_REG, CH32X_REG16_LCR2_LCR, lcr, complete_cb ? ch34x_control_complete : NULL, user_data)); return true; @@ -1395,6 +1395,7 @@ static bool ch34x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, } static void ch34x_set_line_coding_stage1_complete(tuh_xfer_t* xfer) { + // CH34x only has 1 interface and use wIndex as payload and not for bInterfaceNumber uint8_t const itf_num = 0; uint8_t const idx = tuh_cdc_itf_get_index(xfer->daddr, itf_num); cdch_interface_t* p_cdc = get_itf(idx); @@ -1443,7 +1444,7 @@ static bool ch34x_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t con // update transfer result, user_data is expected to point to xfer_result_t if (user_data) { - user_data = result; + *((xfer_result_t*) user_data) = result; } } @@ -1513,8 +1514,7 @@ static void ch34x_process_config(tuh_xfer_t* xfer) { uintptr_t const state = xfer->user_data; uint8_t buffer[2]; // TODO remove TU_ASSERT (p_cdc,); - - // TODO check xfer->result + TU_ASSERT (xfer->result == XFER_RESULT_SUCCESS,); switch (state) { case CONFIG_CH34X_READ_VERSION: @@ -1531,9 +1531,9 @@ static void ch34x_process_config(tuh_xfer_t* xfer) { // init CH34x with line coding cdc_line_coding_t const line_coding = CFG_TUH_CDC_LINE_CODING_ON_ENUM_CH34X; uint16_t const div_ps = ch34x_get_divisor_prescaler(line_coding.bit_rate); - TU_ASSERT(div_ps != 0, ); + TU_ASSERT(div_ps, ); uint8_t const lcr = ch34x_get_lcr(line_coding.stop_bits, line_coding.parity, line_coding.data_bits); - TU_ASSERT(lcr != 0, ); + TU_ASSERT(lcr, ); TU_ASSERT (ch34x_control_out(p_cdc, CH34X_REQ_SERIAL_INIT, tu_u16(lcr, 0x9c), div_ps, ch34x_process_config, CONFIG_CH34X_SPECIAL_REG_WRITE),); break; @@ -1573,7 +1573,7 @@ static uint16_t ch34x_get_divisor_prescaler(uint32_t baval) { uint8_t b; uint32_t c; - TU_VERIFY(baval != 0, 0); + TU_VERIFY(baval != 0 && baval <= 2000000, 0); switch (baval) { case 921600: a = 0xf3; @@ -1627,7 +1627,7 @@ static uint8_t ch34x_get_lcr(uint8_t stop_bits, uint8_t parity, uint8_t data_bit break; case CDC_LINE_CODING_PARITY_ODD: - lcr |= CH34X_LCR_ENABLE_PAR; + lcr |= CH34X_LCR_ENABLE_PAR; break; case CDC_LINE_CODING_PARITY_EVEN: From d1f77e08ac582194578d9587a47201b7d29e0b29 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 2 Feb 2024 13:08:42 +0700 Subject: [PATCH 092/454] build esp32 ci with v5.1 --- .github/workflows/build_esp.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_esp.yml b/.github/workflows/build_esp.yml index 315df255e..8fbdb31ff 100644 --- a/.github/workflows/build_esp.yml +++ b/.github/workflows/build_esp.yml @@ -48,7 +48,7 @@ jobs: uses: actions/checkout@v4 - name: Build - run: docker run --rm -v $PWD:/project -w /project espressif/idf:latest python3 tools/build_esp32.py ${{ matrix.board }} + run: docker run --rm -v $PWD:/project -w /project espressif/idf:v5.1.1 python3 tools/build_esp32.py ${{ matrix.board }} - name: Upload Artifacts for Hardware Testing if: matrix.board == 'espressif_s3_devkitc' && github.repository_owner == 'hathach' From 7ab39cda5f61aa593004db326989e3750e10f191 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 2 Feb 2024 13:17:29 +0700 Subject: [PATCH 093/454] fix rmt legacy driver warning --- hw/bsp/espressif/boards/family.c | 30 +- .../components/led_strip/CHANGELOG.md | 38 ++ .../components/led_strip/CMakeLists.txt | 27 +- hw/bsp/espressif/components/led_strip/LICENSE | 202 ++++++++ .../espressif/components/led_strip/README.md | 97 ++++ hw/bsp/espressif/components/led_strip/api.md | 454 ++++++++++++++++++ .../led_strip_rmt_ws2812/CMakeLists.txt | 9 + .../examples/led_strip_rmt_ws2812/README.md | 31 ++ .../led_strip_rmt_ws2812/dependencies.lock | 15 + .../led_strip_rmt_ws2812/main/CMakeLists.txt | 2 + .../main/idf_component.yml | 5 + .../main/led_strip_rmt_ws2812_main.c | 75 +++ .../components/led_strip/idf_component.yml | 5 + .../components/led_strip/include/led_strip.h | 207 ++++---- .../led_strip/include/led_strip_rmt.h | 53 ++ .../led_strip/include/led_strip_spi.h | 46 ++ .../led_strip/include/led_strip_types.h | 54 +++ .../led_strip/interface/led_strip_interface.h | 95 ++++ .../components/led_strip/src/led_strip_api.c | 94 ++++ .../led_strip/src/led_strip_rmt_dev.c | 164 +++++++ .../led_strip/src/led_strip_rmt_dev_idf4.c | 194 ++++++++ .../led_strip/src/led_strip_rmt_encoder.c | 146 ++++++ .../led_strip/src/led_strip_rmt_encoder.h | 38 ++ .../led_strip/src/led_strip_rmt_ws2812.c | 171 ------- .../led_strip/src/led_strip_spi_dev.c | 209 ++++++++ 25 files changed, 2162 insertions(+), 299 deletions(-) create mode 100644 hw/bsp/espressif/components/led_strip/CHANGELOG.md create mode 100644 hw/bsp/espressif/components/led_strip/LICENSE create mode 100644 hw/bsp/espressif/components/led_strip/README.md create mode 100644 hw/bsp/espressif/components/led_strip/api.md create mode 100644 hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/CMakeLists.txt create mode 100644 hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/README.md create mode 100644 hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/dependencies.lock create mode 100644 hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/main/CMakeLists.txt create mode 100644 hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/main/idf_component.yml create mode 100644 hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/main/led_strip_rmt_ws2812_main.c create mode 100644 hw/bsp/espressif/components/led_strip/idf_component.yml create mode 100644 hw/bsp/espressif/components/led_strip/include/led_strip_rmt.h create mode 100644 hw/bsp/espressif/components/led_strip/include/led_strip_spi.h create mode 100644 hw/bsp/espressif/components/led_strip/include/led_strip_types.h create mode 100644 hw/bsp/espressif/components/led_strip/interface/led_strip_interface.h create mode 100644 hw/bsp/espressif/components/led_strip/src/led_strip_api.c create mode 100644 hw/bsp/espressif/components/led_strip/src/led_strip_rmt_dev.c create mode 100644 hw/bsp/espressif/components/led_strip/src/led_strip_rmt_dev_idf4.c create mode 100644 hw/bsp/espressif/components/led_strip/src/led_strip_rmt_encoder.c create mode 100644 hw/bsp/espressif/components/led_strip/src/led_strip_rmt_encoder.h delete mode 100644 hw/bsp/espressif/components/led_strip/src/led_strip_rmt_ws2812.c create mode 100644 hw/bsp/espressif/components/led_strip/src/led_strip_spi_dev.c diff --git a/hw/bsp/espressif/boards/family.c b/hw/bsp/espressif/boards/family.c index 325e9ab0f..5599d1504 100644 --- a/hw/bsp/espressif/boards/family.c +++ b/hw/bsp/espressif/boards/family.c @@ -33,7 +33,7 @@ #include "hal/usb_hal.h" #include "soc/usb_periph.h" -#include "driver/rmt.h" +#include "driver/gpio.h" #include "driver/uart.h" #if ESP_IDF_VERSION_MAJOR > 4 @@ -48,7 +48,7 @@ #ifdef NEOPIXEL_PIN #include "led_strip.h" -static led_strip_t* strip; +static led_strip_handle_t led_strip; #endif #if CFG_TUH_ENABLED && CFG_TUH_MAX3421 @@ -85,15 +85,23 @@ void board_init(void) { #endif // WS2812 Neopixel driver with RMT peripheral - rmt_config_t config = RMT_DEFAULT_CONFIG_TX(NEOPIXEL_PIN, RMT_CHANNEL_0); - config.clk_div = 2; // set counter clock to 40MHz + led_strip_rmt_config_t rmt_config = { + .clk_src = RMT_CLK_SRC_DEFAULT, // different clock source can lead to different power consumption + .resolution_hz = 10 * 1000 * 1000, // RMT counter clock frequency, default = 10 Mhz + .flags.with_dma = false, // DMA feature is available on ESP target like ESP32-S3 + }; - rmt_config(&config); - rmt_driver_install(config.channel, 0, 0); + led_strip_config_t strip_config = { + .strip_gpio_num = NEOPIXEL_PIN, // The GPIO that connected to the LED strip's data line + .max_leds = 1, // The number of LEDs in the strip, + .led_pixel_format = LED_PIXEL_FORMAT_GRB, // Pixel format of your LED strip + .led_model = LED_MODEL_WS2812, // LED strip model + .flags.invert_out = false, // whether to invert the output signal + }; - led_strip_config_t strip_config = LED_STRIP_DEFAULT_CONFIG(1, (led_strip_dev_t) config.channel); - strip = led_strip_new_rmt_ws2812(&strip_config); - strip->clear(strip, 100); // off led + ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip)); + + led_strip_clear(led_strip); // off #endif // Button @@ -158,8 +166,8 @@ size_t board_get_unique_id(uint8_t id[], size_t max_len) { void board_led_write(bool state) { #ifdef NEOPIXEL_PIN - strip->set_pixel(strip, 0, state ? 0x08 : 0x00, 0x00, 0x00); - strip->refresh(strip, 100); + led_strip_set_pixel(led_strip, 0, state ? 0x08 : 0x00, 0x00, 0x00); + led_strip_refresh(led_strip); #endif } diff --git a/hw/bsp/espressif/components/led_strip/CHANGELOG.md b/hw/bsp/espressif/components/led_strip/CHANGELOG.md new file mode 100644 index 000000000..51c0cd30c --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/CHANGELOG.md @@ -0,0 +1,38 @@ +## 2.5.0 + +- Enabled support for IDF4.4 and above + - with RMT backend only +- Added API `led_strip_set_pixel_hsv` + +## 2.4.0 + +- Support configurable SPI mode to control leds + - recommend enabling DMA when using SPI mode + +## 2.3.0 + +- Support configurable RMT channel size by setting `mem_block_symbols` + +## 2.2.0 + +- Support for 4 components RGBW leds (SK6812): + - in led_strip_config_t new fields + led_pixel_format, controlling byte format (LED_PIXEL_FORMAT_GRB, LED_PIXEL_FORMAT_GRBW) + led_model, used to configure bit timing (LED_MODEL_WS2812, LED_MODEL_SK6812) + - new API led_strip_set_pixel_rgbw + - new interface type set_pixel_rgbw + +## 2.1.0 + +- Support DMA feature, which offloads the CPU by a lot when it comes to drive a bunch of LEDs +- Support various RMT clock sources +- Acquire and release the power management lock before and after each refresh +- New driver flag: `invert_out` which can invert the led control signal by hardware + +## 2.0.0 + +- Reimplemented the driver using the new RMT driver (`driver/rmt_tx.h`) + +## 1.0.0 + +- Initial driver version, based on the legacy RMT driver (`driver/rmt.h`) diff --git a/hw/bsp/espressif/components/led_strip/CMakeLists.txt b/hw/bsp/espressif/components/led_strip/CMakeLists.txt index 8266c5a1c..15de610cc 100644 --- a/hw/bsp/espressif/components/led_strip/CMakeLists.txt +++ b/hw/bsp/espressif/components/led_strip/CMakeLists.txt @@ -1,7 +1,22 @@ -set(component_srcs "src/led_strip_rmt_ws2812.c") +include($ENV{IDF_PATH}/tools/cmake/version.cmake) -idf_component_register(SRCS "${component_srcs}" - INCLUDE_DIRS "include" - PRIV_INCLUDE_DIRS "" - PRIV_REQUIRES "driver" - REQUIRES "") +set(srcs "src/led_strip_api.c") + +if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER_EQUAL "5.0") + if(CONFIG_SOC_RMT_SUPPORTED) + list(APPEND srcs "src/led_strip_rmt_dev.c" "src/led_strip_rmt_encoder.c") + endif() +else() + list(APPEND srcs "src/led_strip_rmt_dev_idf4.c") +endif() + +# the SPI backend driver relies on something that was added in IDF 5.1 +if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER_EQUAL "5.1") + if(CONFIG_SOC_GPSPI_SUPPORTED) + list(APPEND srcs "src/led_strip_spi_dev.c") + endif() +endif() + +idf_component_register(SRCS ${srcs} + INCLUDE_DIRS "include" "interface" + REQUIRES "driver") diff --git a/hw/bsp/espressif/components/led_strip/LICENSE b/hw/bsp/espressif/components/led_strip/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/hw/bsp/espressif/components/led_strip/README.md b/hw/bsp/espressif/components/led_strip/README.md new file mode 100644 index 000000000..543d29642 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/README.md @@ -0,0 +1,97 @@ +# LED Strip Driver + +[![Component Registry](https://components.espressif.com/components/espressif/led_strip/badge.svg)](https://components.espressif.com/components/espressif/led_strip) + +This driver is designed for addressable LEDs like [WS2812](http://www.world-semi.com/Certifications/WS2812B.html), where each LED is controlled by a single data line. + +## Backend Controllers + +### The [RMT](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/rmt.html) Peripheral + +This is the most economical way to drive the LEDs because it only consumes one RMT channel, leaving other channels free to use. However, the memory usage increases dramatically with the number of LEDs. If the RMT hardware can't be assist by DMA, the driver will going into interrupt very frequently, thus result in a high CPU usage. What's worse, if the RMT interrupt is delayed or not serviced in time (e.g. if Wi-Fi interrupt happens on the same CPU core), the RMT transaction will be corrupted and the LEDs will display incorrect colors. If you want to use RMT to drive a large number of LEDs, you'd better to enable the DMA feature if possible [^1]. + +#### Allocate LED Strip Object with RMT Backend + +```c +#define BLINK_GPIO 0 + +led_strip_handle_t led_strip; + +/* LED strip initialization with the GPIO and pixels number*/ +led_strip_config_t strip_config = { + .strip_gpio_num = BLINK_GPIO, // The GPIO that connected to the LED strip's data line + .max_leds = 1, // The number of LEDs in the strip, + .led_pixel_format = LED_PIXEL_FORMAT_GRB, // Pixel format of your LED strip + .led_model = LED_MODEL_WS2812, // LED strip model + .flags.invert_out = false, // whether to invert the output signal (useful when your hardware has a level inverter) +}; + +led_strip_rmt_config_t rmt_config = { +#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) + .rmt_channel = 0, +#else + .clk_src = RMT_CLK_SRC_DEFAULT, // different clock source can lead to different power consumption + .resolution_hz = 10 * 1000 * 1000, // 10MHz + .flags.with_dma = false, // whether to enable the DMA feature +#endif +}; +ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip)); +``` + +You can create multiple LED strip objects with different GPIOs and pixel numbers. The backend driver will automatically allocate the RMT channel for you if there is more available. + +### The [SPI](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/spi_master.html) Peripheral + +SPI peripheral can also be used to generate the timing required by the LED strip. However this backend is not as economical as the RMT one, because it will take up the whole **bus**, unlike the RMT just takes one **channel**. You **CAN'T** connect other devices to the same SPI bus if it's been used by the led_strip, because the led_strip doesn't have the concept of "Chip Select". + +Please note, the SPI backend has a dependency of **ESP-IDF >= 5.1** + +#### Allocate LED Strip Object with SPI Backend + +```c +#define BLINK_GPIO 0 + +led_strip_handle_t led_strip; + +/* LED strip initialization with the GPIO and pixels number*/ +led_strip_config_t strip_config = { + .strip_gpio_num = BLINK_GPIO, // The GPIO that connected to the LED strip's data line + .max_leds = 1, // The number of LEDs in the strip, + .led_pixel_format = LED_PIXEL_FORMAT_GRB, // Pixel format of your LED strip + .led_model = LED_MODEL_WS2812, // LED strip model + .flags.invert_out = false, // whether to invert the output signal (useful when your hardware has a level inverter) +}; + +led_strip_spi_config_t spi_config = { + .clk_src = SPI_CLK_SRC_DEFAULT, // different clock source can lead to different power consumption + .flags.with_dma = true, // Using DMA can improve performance and help drive more LEDs + .spi_bus = SPI2_HOST, // SPI bus ID +}; +ESP_ERROR_CHECK(led_strip_new_spi_device(&strip_config, &spi_config, &led_strip)); +``` + +The number of LED strip objects can be created depends on how many free SPI buses are free to use in your project. + +## FAQ + +* Which led_strip backend should I choose? + * It depends on your application requirement and target chip's ability. + + ```mermaid + flowchart LR + A{Is RMT supported?} + A --> |No| B[SPI backend] + B --> C{Does the led strip has \n a larger number of LEDs?} + C --> |No| D[Don't have to enable the DMA of the backend] + C --> |Yes| E[Enable the DMA of the backend] + A --> |Yes| F{Does the led strip has \n a larger number of LEDs?} + F --> |Yes| G{Does RMT support DMA?} + G --> |Yes| E + G --> |No| B + F --> |No| H[RMT backend] --> D + ``` + +* How to set the brightness of the LED strip? + * You can tune the brightness by scaling the value of each R-G-B element with a **same** factor. But pay attention to the overflow of the value. + +[^1]: The RMT DMA feature is not available on all ESP chips. Please check the data sheet before using it. diff --git a/hw/bsp/espressif/components/led_strip/api.md b/hw/bsp/espressif/components/led_strip/api.md new file mode 100644 index 000000000..6581d6604 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/api.md @@ -0,0 +1,454 @@ +# API Reference + +## Header files + +- [include/led_strip.h](#file-includeled_striph) +- [include/led_strip_rmt.h](#file-includeled_strip_rmth) +- [include/led_strip_spi.h](#file-includeled_strip_spih) +- [include/led_strip_types.h](#file-includeled_strip_typesh) +- [interface/led_strip_interface.h](#file-interfaceled_strip_interfaceh) + +## File include/led_strip.h + +## Functions + +| Type | Name | +| ---: | :--- | +| esp\_err\_t | [**led\_strip\_clear**](#function-led_strip_clear) ([**led\_strip\_handle\_t**](#struct-led_strip_t) strip)
_Clear LED strip (turn off all LEDs)_ | +| esp\_err\_t | [**led\_strip\_del**](#function-led_strip_del) ([**led\_strip\_handle\_t**](#struct-led_strip_t) strip)
_Free LED strip resources._ | +| esp\_err\_t | [**led\_strip\_refresh**](#function-led_strip_refresh) ([**led\_strip\_handle\_t**](#struct-led_strip_t) strip)
_Refresh memory colors to LEDs._ | +| esp\_err\_t | [**led\_strip\_set\_pixel**](#function-led_strip_set_pixel) ([**led\_strip\_handle\_t**](#struct-led_strip_t) strip, uint32\_t index, uint32\_t red, uint32\_t green, uint32\_t blue)
_Set RGB for a specific pixel._ | +| esp\_err\_t | [**led\_strip\_set\_pixel\_hsv**](#function-led_strip_set_pixel_hsv) ([**led\_strip\_handle\_t**](#struct-led_strip_t) strip, uint32\_t index, uint16\_t hue, uint8\_t saturation, uint8\_t value)
_Set HSV for a specific pixel._ | +| esp\_err\_t | [**led\_strip\_set\_pixel\_rgbw**](#function-led_strip_set_pixel_rgbw) ([**led\_strip\_handle\_t**](#struct-led_strip_t) strip, uint32\_t index, uint32\_t red, uint32\_t green, uint32\_t blue, uint32\_t white)
_Set RGBW for a specific pixel._ | + +## Functions Documentation + +### function `led_strip_clear` + +_Clear LED strip (turn off all LEDs)_ + +```c +esp_err_t led_strip_clear ( + led_strip_handle_t strip +) +``` + +**Parameters:** + +- `strip` LED strip + +**Returns:** + +- ESP\_OK: Clear LEDs successfully +- ESP\_FAIL: Clear LEDs failed because some other error occurred + +### function `led_strip_del` + +_Free LED strip resources._ + +```c +esp_err_t led_strip_del ( + led_strip_handle_t strip +) +``` + +**Parameters:** + +- `strip` LED strip + +**Returns:** + +- ESP\_OK: Free resources successfully +- ESP\_FAIL: Free resources failed because error occurred + +### function `led_strip_refresh` + +_Refresh memory colors to LEDs._ + +```c +esp_err_t led_strip_refresh ( + led_strip_handle_t strip +) +``` + +**Parameters:** + +- `strip` LED strip + +**Returns:** + +- ESP\_OK: Refresh successfully +- ESP\_FAIL: Refresh failed because some other error occurred + +**Note:** + +: After updating the LED colors in the memory, a following invocation of this API is needed to flush colors to strip. + +### function `led_strip_set_pixel` + +_Set RGB for a specific pixel._ + +```c +esp_err_t led_strip_set_pixel ( + led_strip_handle_t strip, + uint32_t index, + uint32_t red, + uint32_t green, + uint32_t blue +) +``` + +**Parameters:** + +- `strip` LED strip +- `index` index of pixel to set +- `red` red part of color +- `green` green part of color +- `blue` blue part of color + +**Returns:** + +- ESP\_OK: Set RGB for a specific pixel successfully +- ESP\_ERR\_INVALID\_ARG: Set RGB for a specific pixel failed because of invalid parameters +- ESP\_FAIL: Set RGB for a specific pixel failed because other error occurred + +### function `led_strip_set_pixel_hsv` + +_Set HSV for a specific pixel._ + +```c +esp_err_t led_strip_set_pixel_hsv ( + led_strip_handle_t strip, + uint32_t index, + uint16_t hue, + uint8_t saturation, + uint8_t value +) +``` + +**Parameters:** + +- `strip` LED strip +- `index` index of pixel to set +- `hue` hue part of color (0 - 360) +- `saturation` saturation part of color (0 - 255) +- `value` value part of color (0 - 255) + +**Returns:** + +- ESP\_OK: Set HSV color for a specific pixel successfully +- ESP\_ERR\_INVALID\_ARG: Set HSV color for a specific pixel failed because of an invalid argument +- ESP\_FAIL: Set HSV color for a specific pixel failed because other error occurred + +### function `led_strip_set_pixel_rgbw` + +_Set RGBW for a specific pixel._ + +```c +esp_err_t led_strip_set_pixel_rgbw ( + led_strip_handle_t strip, + uint32_t index, + uint32_t red, + uint32_t green, + uint32_t blue, + uint32_t white +) +``` + +**Note:** + +Only call this function if your led strip does have the white component (e.g. SK6812-RGBW) + +**Note:** + +Also see `led_strip_set_pixel` if you only want to specify the RGB part of the color and bypass the white component + +**Parameters:** + +- `strip` LED strip +- `index` index of pixel to set +- `red` red part of color +- `green` green part of color +- `blue` blue part of color +- `white` separate white component + +**Returns:** + +- ESP\_OK: Set RGBW color for a specific pixel successfully +- ESP\_ERR\_INVALID\_ARG: Set RGBW color for a specific pixel failed because of an invalid argument +- ESP\_FAIL: Set RGBW color for a specific pixel failed because other error occurred + +## File include/led_strip_rmt.h + +## Structures and Types + +| Type | Name | +| ---: | :--- | +| struct | [**led\_strip\_rmt\_config\_t**](#struct-led_strip_rmt_config_t)
_LED Strip RMT specific configuration._ | + +## Functions + +| Type | Name | +| ---: | :--- | +| esp\_err\_t | [**led\_strip\_new\_rmt\_device**](#function-led_strip_new_rmt_device) (const [**led\_strip\_config\_t**](#struct-led_strip_config_t) \*led\_config, const [**led\_strip\_rmt\_config\_t**](#struct-led_strip_rmt_config_t) \*rmt\_config, [**led\_strip\_handle\_t**](#struct-led_strip_t) \*ret\_strip)
_Create LED strip based on RMT TX channel._ | + +## Structures and Types Documentation + +### struct `led_strip_rmt_config_t` + +_LED Strip RMT specific configuration._ + +Variables: + +- rmt\_clock\_source\_t clk_src
RMT clock source + +- struct [**led\_strip\_rmt\_config\_t**](#struct-led_strip_rmt_config_t) flags
Extra driver flags + +- size\_t mem_block_symbols
How many RMT symbols can one RMT channel hold at one time. Set to 0 will fallback to use the default size. + +- uint32\_t resolution_hz
RMT tick resolution, if set to zero, a default resolution (10MHz) will be applied + +- uint32\_t with_dma
Use DMA to transmit data + +## Functions Documentation + +### function `led_strip_new_rmt_device` + +_Create LED strip based on RMT TX channel._ + +```c +esp_err_t led_strip_new_rmt_device ( + const led_strip_config_t *led_config, + const led_strip_rmt_config_t *rmt_config, + led_strip_handle_t *ret_strip +) +``` + +**Parameters:** + +- `led_config` LED strip configuration +- `rmt_config` RMT specific configuration +- `ret_strip` Returned LED strip handle + +**Returns:** + +- ESP\_OK: create LED strip handle successfully +- ESP\_ERR\_INVALID\_ARG: create LED strip handle failed because of invalid argument +- ESP\_ERR\_NO\_MEM: create LED strip handle failed because of out of memory +- ESP\_FAIL: create LED strip handle failed because some other error + +## File include/led_strip_spi.h + +## Structures and Types + +| Type | Name | +| ---: | :--- | +| struct | [**led\_strip\_spi\_config\_t**](#struct-led_strip_spi_config_t)
_LED Strip SPI specific configuration._ | + +## Functions + +| Type | Name | +| ---: | :--- | +| esp\_err\_t | [**led\_strip\_new\_spi\_device**](#function-led_strip_new_spi_device) (const [**led\_strip\_config\_t**](#struct-led_strip_config_t) \*led\_config, const [**led\_strip\_spi\_config\_t**](#struct-led_strip_spi_config_t) \*spi\_config, [**led\_strip\_handle\_t**](#struct-led_strip_t) \*ret\_strip)
_Create LED strip based on SPI MOSI channel._ | + +## Structures and Types Documentation + +### struct `led_strip_spi_config_t` + +_LED Strip SPI specific configuration._ + +Variables: + +- spi\_clock\_source\_t clk_src
SPI clock source + +- struct [**led\_strip\_spi\_config\_t**](#struct-led_strip_spi_config_t) flags
Extra driver flags + +- spi\_host\_device\_t spi_bus
SPI bus ID. Which buses are available depends on the specific chip + +- uint32\_t with_dma
Use DMA to transmit data + +## Functions Documentation + +### function `led_strip_new_spi_device` + +_Create LED strip based on SPI MOSI channel._ + +```c +esp_err_t led_strip_new_spi_device ( + const led_strip_config_t *led_config, + const led_strip_spi_config_t *spi_config, + led_strip_handle_t *ret_strip +) +``` + +**Note:** + +Although only the MOSI line is used for generating the signal, the whole SPI bus can't be used for other purposes. + +**Parameters:** + +- `led_config` LED strip configuration +- `spi_config` SPI specific configuration +- `ret_strip` Returned LED strip handle + +**Returns:** + +- ESP\_OK: create LED strip handle successfully +- ESP\_ERR\_INVALID\_ARG: create LED strip handle failed because of invalid argument +- ESP\_ERR\_NOT\_SUPPORTED: create LED strip handle failed because of unsupported configuration +- ESP\_ERR\_NO\_MEM: create LED strip handle failed because of out of memory +- ESP\_FAIL: create LED strip handle failed because some other error + +## File include/led_strip_types.h + +## Structures and Types + +| Type | Name | +| ---: | :--- | +| enum | [**led\_model\_t**](#enum-led_model_t)
_LED strip model._ | +| enum | [**led\_pixel\_format\_t**](#enum-led_pixel_format_t)
_LED strip pixel format._ | +| struct | [**led\_strip\_config\_t**](#struct-led_strip_config_t)
_LED Strip Configuration._ | +| typedef struct [**led\_strip\_t**](#struct-led_strip_t) \* | [**led\_strip\_handle\_t**](#typedef-led_strip_handle_t)
_LED strip handle._ | + +## Structures and Types Documentation + +### enum `led_model_t` + +_LED strip model._ + +```c +enum led_model_t { + LED_MODEL_WS2812, + LED_MODEL_SK6812, + LED_MODEL_INVALID +}; +``` + +**Note:** + +Different led model may have different timing parameters, so we need to distinguish them. + +### enum `led_pixel_format_t` + +_LED strip pixel format._ + +```c +enum led_pixel_format_t { + LED_PIXEL_FORMAT_GRB, + LED_PIXEL_FORMAT_GRBW, + LED_PIXEL_FORMAT_INVALID +}; +``` + +### struct `led_strip_config_t` + +_LED Strip Configuration._ + +Variables: + +- struct [**led\_strip\_config\_t**](#struct-led_strip_config_t) flags
Extra driver flags + +- uint32\_t invert_out
Invert output signal + +- led\_model\_t led_model
LED model + +- led\_pixel\_format\_t led_pixel_format
LED pixel format + +- uint32\_t max_leds
Maximum LEDs in a single strip + +- int strip_gpio_num
GPIO number that used by LED strip + +### typedef `led_strip_handle_t` + +_LED strip handle._ + +```c +typedef struct led_strip_t* led_strip_handle_t; +``` + +## File interface/led_strip_interface.h + +## Structures and Types + +| Type | Name | +| ---: | :--- | +| struct | [**led\_strip\_t**](#struct-led_strip_t)
_LED strip interface definition._ | +| typedef struct [**led\_strip\_t**](#struct-led_strip_t) | [**led\_strip\_t**](#typedef-led_strip_t)
| + +## Structures and Types Documentation + +### struct `led_strip_t` + +_LED strip interface definition._ + +Variables: + +- esp\_err\_t(\* clear
_Clear LED strip (turn off all LEDs)_
**Parameters:** + +- `strip` LED strip +- `timeout_ms` timeout value for clearing task + +**Returns:** + +- ESP\_OK: Clear LEDs successfully +- ESP\_FAIL: Clear LEDs failed because some other error occurred + +- esp\_err\_t(\* del
_Free LED strip resources._
**Parameters:** + +- `strip` LED strip + +**Returns:** + +- ESP\_OK: Free resources successfully +- ESP\_FAIL: Free resources failed because error occurred + +- esp\_err\_t(\* refresh
_Refresh memory colors to LEDs._
**Parameters:** + +- `strip` LED strip +- `timeout_ms` timeout value for refreshing task + +**Returns:** + +- ESP\_OK: Refresh successfully +- ESP\_FAIL: Refresh failed because some other error occurred + +**Note:** + +: After updating the LED colors in the memory, a following invocation of this API is needed to flush colors to strip. + +- esp\_err\_t(\* set_pixel
_Set RGB for a specific pixel._
**Parameters:** + +- `strip` LED strip +- `index` index of pixel to set +- `red` red part of color +- `green` green part of color +- `blue` blue part of color + +**Returns:** + +- ESP\_OK: Set RGB for a specific pixel successfully +- ESP\_ERR\_INVALID\_ARG: Set RGB for a specific pixel failed because of invalid parameters +- ESP\_FAIL: Set RGB for a specific pixel failed because other error occurred + +- esp\_err\_t(\* set_pixel_rgbw
_Set RGBW for a specific pixel. Similar to_ `set_pixel`_but also set the white component._
**Parameters:** + +- `strip` LED strip +- `index` index of pixel to set +- `red` red part of color +- `green` green part of color +- `blue` blue part of color +- `white` separate white component + +**Returns:** + +- ESP\_OK: Set RGBW color for a specific pixel successfully +- ESP\_ERR\_INVALID\_ARG: Set RGBW color for a specific pixel failed because of an invalid argument +- ESP\_FAIL: Set RGBW color for a specific pixel failed because other error occurred + +### typedef `led_strip_t` + +```c +typedef struct led_strip_t led_strip_t; +``` + +Type of LED strip diff --git a/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/CMakeLists.txt b/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/CMakeLists.txt new file mode 100644 index 000000000..923c46310 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/CMakeLists.txt @@ -0,0 +1,9 @@ +# For more information about build system see +# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html +# The following five lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +set(IDF_TARGET "esp32s3") +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(led_strip_rmt_ws2812) diff --git a/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/README.md b/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/README.md new file mode 100644 index 000000000..ad52235d5 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/README.md @@ -0,0 +1,31 @@ +# LED Strip Example (RMT backend + WS2812) + +This example demonstrates how to blink the WS2812 LED using the [led_strip](https://components.espressif.com/component/espressif/led_strip) component. + +## How to Use Example + +### Hardware Required + +* A development board with Espressif SoC +* A USB cable for Power supply and programming +* WS2812 LED strip + +### Configure the Example + +Before project configuration and build, be sure to set the correct chip target using `idf.py set-target `. Then assign the proper GPIO in the [source file](main/led_strip_rmt_ws2812_main.c). If your led strip has multiple LEDs, don't forget update the number. + +### Build and Flash + +Run `idf.py -p PORT build flash monitor` to build, flash and monitor the project. + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects. + +## Example Output + +```text +I (299) gpio: GPIO[8]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 +I (309) example: Created LED strip object with RMT backend +I (309) example: Start blinking LED strip +``` 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 new file mode 100644 index 000000000..97840a153 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/dependencies.lock @@ -0,0 +1,15 @@ +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/espressif/components/led_strip/examples/led_strip_rmt_ws2812/main/CMakeLists.txt b/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/main/CMakeLists.txt new file mode 100644 index 000000000..37b9c1458 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "led_strip_rmt_ws2812_main.c" + INCLUDE_DIRS ".") diff --git a/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/main/idf_component.yml b/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/main/idf_component.yml new file mode 100644 index 000000000..916c366c7 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/main/idf_component.yml @@ -0,0 +1,5 @@ +## IDF Component Manager Manifest File +dependencies: + espressif/led_strip: + version: '^2' + override_path: '../../../' diff --git a/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/main/led_strip_rmt_ws2812_main.c b/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/main/led_strip_rmt_ws2812_main.c new file mode 100644 index 000000000..4b20a5958 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/main/led_strip_rmt_ws2812_main.c @@ -0,0 +1,75 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "led_strip.h" +#include "esp_log.h" +#include "esp_err.h" + +// GPIO assignment +#define LED_STRIP_BLINK_GPIO 48 +// Numbers of the LED in the strip +#define LED_STRIP_LED_NUMBERS 1 +// 10MHz resolution, 1 tick = 0.1us (led strip needs a high resolution) +#define LED_STRIP_RMT_RES_HZ (10 * 1000 * 1000) + +static const char *TAG = "example"; + +led_strip_handle_t configure_led(void) +{ + // LED strip general initialization, according to your led board design + led_strip_config_t strip_config = { + .strip_gpio_num = LED_STRIP_BLINK_GPIO, // The GPIO that connected to the LED strip's data line + .max_leds = LED_STRIP_LED_NUMBERS, // The number of LEDs in the strip, + .led_pixel_format = LED_PIXEL_FORMAT_GRB, // Pixel format of your LED strip + .led_model = LED_MODEL_WS2812, // LED strip model + .flags.invert_out = false, // whether to invert the output signal + }; + + // LED strip backend configuration: RMT + led_strip_rmt_config_t rmt_config = { +#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) + .rmt_channel = 0, +#else + .clk_src = RMT_CLK_SRC_DEFAULT, // different clock source can lead to different power consumption + .resolution_hz = LED_STRIP_RMT_RES_HZ, // RMT counter clock frequency + .flags.with_dma = false, // DMA feature is available on ESP target like ESP32-S3 +#endif + }; + + // LED Strip object handle + led_strip_handle_t led_strip; + ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip)); + ESP_LOGI(TAG, "Created LED strip object with RMT backend"); + return led_strip; +} + +void app_main(void) +{ + led_strip_handle_t led_strip = configure_led(); + bool led_on_off = false; + + ESP_LOGI(TAG, "Start blinking LED strip"); + while (1) { + if (led_on_off) { + /* Set the LED pixel using RGB from 0 (0%) to 255 (100%) for each color */ + for (int i = 0; i < LED_STRIP_LED_NUMBERS; i++) { + ESP_ERROR_CHECK(led_strip_set_pixel(led_strip, i, 5, 5, 5)); + } + /* Refresh the strip to send data */ + ESP_ERROR_CHECK(led_strip_refresh(led_strip)); + ESP_LOGI(TAG, "LED ON!"); + } else { + /* Set all LED off to clear all pixels */ + ESP_ERROR_CHECK(led_strip_clear(led_strip)); + ESP_LOGI(TAG, "LED OFF!"); + } + + led_on_off = !led_on_off; + vTaskDelay(pdMS_TO_TICKS(500)); + } +} diff --git a/hw/bsp/espressif/components/led_strip/idf_component.yml b/hw/bsp/espressif/components/led_strip/idf_component.yml new file mode 100644 index 000000000..1fd9b83ee --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/idf_component.yml @@ -0,0 +1,5 @@ +version: "2.5.2" +description: Driver for Addressable LED Strip (WS2812, etc) +url: https://github.com/espressif/idf-extra-components/tree/master/led_strip +dependencies: + idf: ">=4.4" diff --git a/hw/bsp/espressif/components/led_strip/include/led_strip.h b/hw/bsp/espressif/components/led_strip/include/led_strip.h index a9dffc325..38711744a 100644 --- a/hw/bsp/espressif/components/led_strip/include/led_strip.h +++ b/hw/bsp/espressif/components/led_strip/include/led_strip.h @@ -1,125 +1,110 @@ -// Copyright 2019 Espressif Systems (Shanghai) PTE LTD -// -// 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. +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once +#include +#include "esp_err.h" +#include "led_strip_rmt.h" +#include "esp_idf_version.h" + +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0) +#include "led_strip_spi.h" +#endif + #ifdef __cplusplus extern "C" { #endif -#include "esp_err.h" - /** -* @brief LED Strip Type -* -*/ -typedef struct led_strip_s led_strip_t; - -/** -* @brief LED Strip Device Type -* -*/ -typedef void *led_strip_dev_t; - -/** -* @brief Declare of LED Strip Type -* -*/ -struct led_strip_s { - /** - * @brief Set RGB for a specific pixel - * - * @param strip: LED strip - * @param index: index of pixel to set - * @param red: red part of color - * @param green: green part of color - * @param blue: blue part of color - * - * @return - * - ESP_OK: Set RGB for a specific pixel successfully - * - ESP_ERR_INVALID_ARG: Set RGB for a specific pixel failed because of invalid parameters - * - ESP_FAIL: Set RGB for a specific pixel failed because other error occurred - */ - esp_err_t (*set_pixel)(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue); - - /** - * @brief Refresh memory colors to LEDs - * - * @param strip: LED strip - * @param timeout_ms: timeout value for refreshing task - * - * @return - * - ESP_OK: Refresh successfully - * - ESP_ERR_TIMEOUT: Refresh failed because of timeout - * - ESP_FAIL: Refresh failed because some other error occurred - * - * @note: - * After updating the LED colors in the memory, a following invocation of this API is needed to flush colors to strip. - */ - esp_err_t (*refresh)(led_strip_t *strip, uint32_t timeout_ms); - - /** - * @brief Clear LED strip (turn off all LEDs) - * - * @param strip: LED strip - * @param timeout_ms: timeout value for clearing task - * - * @return - * - ESP_OK: Clear LEDs successfully - * - ESP_ERR_TIMEOUT: Clear LEDs failed because of timeout - * - ESP_FAIL: Clear LEDs failed because some other error occurred - */ - esp_err_t (*clear)(led_strip_t *strip, uint32_t timeout_ms); - - /** - * @brief Free LED strip resources - * - * @param strip: LED strip - * - * @return - * - ESP_OK: Free resources successfully - * - ESP_FAIL: Free resources failed because error occurred - */ - esp_err_t (*del)(led_strip_t *strip); -}; - -/** -* @brief LED Strip Configuration Type -* -*/ -typedef struct { - uint32_t max_leds; /*!< Maximum LEDs in a single strip */ - led_strip_dev_t dev; /*!< LED strip device (e.g. RMT channel, PWM channel, etc) */ -} led_strip_config_t; - -/** - * @brief Default configuration for LED strip + * @brief Set RGB for a specific pixel * + * @param strip: LED strip + * @param index: index of pixel to set + * @param red: red part of color + * @param green: green part of color + * @param blue: blue part of color + * + * @return + * - ESP_OK: Set RGB for a specific pixel successfully + * - ESP_ERR_INVALID_ARG: Set RGB for a specific pixel failed because of invalid parameters + * - ESP_FAIL: Set RGB for a specific pixel failed because other error occurred */ -#define LED_STRIP_DEFAULT_CONFIG(number, dev_hdl) \ - { \ - .max_leds = number, \ - .dev = dev_hdl, \ - } +esp_err_t led_strip_set_pixel(led_strip_handle_t strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue); /** -* @brief Install a new ws2812 driver (based on RMT peripheral) -* -* @param config: LED strip configuration -* @return -* LED strip instance or NULL -*/ -led_strip_t *led_strip_new_rmt_ws2812(const led_strip_config_t *config); + * @brief Set RGBW for a specific pixel + * + * @note Only call this function if your led strip does have the white component (e.g. SK6812-RGBW) + * @note Also see `led_strip_set_pixel` if you only want to specify the RGB part of the color and bypass the white component + * + * @param strip: LED strip + * @param index: index of pixel to set + * @param red: red part of color + * @param green: green part of color + * @param blue: blue part of color + * @param white: separate white component + * + * @return + * - ESP_OK: Set RGBW color for a specific pixel successfully + * - ESP_ERR_INVALID_ARG: Set RGBW color for a specific pixel failed because of an invalid argument + * - ESP_FAIL: Set RGBW color for a specific pixel failed because other error occurred + */ +esp_err_t led_strip_set_pixel_rgbw(led_strip_handle_t strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue, uint32_t white); + +/** + * @brief Set HSV for a specific pixel + * + * @param strip: LED strip + * @param index: index of pixel to set + * @param hue: hue part of color (0 - 360) + * @param saturation: saturation part of color (0 - 255) + * @param value: value part of color (0 - 255) + * + * @return + * - ESP_OK: Set HSV color for a specific pixel successfully + * - ESP_ERR_INVALID_ARG: Set HSV color for a specific pixel failed because of an invalid argument + * - ESP_FAIL: Set HSV color for a specific pixel failed because other error occurred + */ +esp_err_t led_strip_set_pixel_hsv(led_strip_handle_t strip, uint32_t index, uint16_t hue, uint8_t saturation, uint8_t value); + +/** + * @brief Refresh memory colors to LEDs + * + * @param strip: LED strip + * + * @return + * - ESP_OK: Refresh successfully + * - ESP_FAIL: Refresh failed because some other error occurred + * + * @note: + * After updating the LED colors in the memory, a following invocation of this API is needed to flush colors to strip. + */ +esp_err_t led_strip_refresh(led_strip_handle_t strip); + +/** + * @brief Clear LED strip (turn off all LEDs) + * + * @param strip: LED strip + * + * @return + * - ESP_OK: Clear LEDs successfully + * - ESP_FAIL: Clear LEDs failed because some other error occurred + */ +esp_err_t led_strip_clear(led_strip_handle_t strip); + +/** + * @brief Free LED strip resources + * + * @param strip: LED strip + * + * @return + * - ESP_OK: Free resources successfully + * - ESP_FAIL: Free resources failed because error occurred + */ +esp_err_t led_strip_del(led_strip_handle_t strip); #ifdef __cplusplus } diff --git a/hw/bsp/espressif/components/led_strip/include/led_strip_rmt.h b/hw/bsp/espressif/components/led_strip/include/led_strip_rmt.h new file mode 100644 index 000000000..b575aeaba --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/include/led_strip_rmt.h @@ -0,0 +1,53 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include "esp_err.h" +#include "led_strip_types.h" +#include "esp_idf_version.h" + +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) +#include "driver/rmt_types.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief LED Strip RMT specific configuration + */ +typedef struct { +#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) + uint8_t rmt_channel; /*!< Specify the channel number, the legacy RMT driver doesn't support channel allocator */ +#else // new driver supports specify the clock source and clock resolution + rmt_clock_source_t clk_src; /*!< RMT clock source */ + uint32_t resolution_hz; /*!< RMT tick resolution, if set to zero, a default resolution (10MHz) will be applied */ +#endif + size_t mem_block_symbols; /*!< How many RMT symbols can one RMT channel hold at one time. Set to 0 will fallback to use the default size. */ + struct { + uint32_t with_dma: 1; /*!< Use DMA to transmit data */ + } flags; /*!< Extra driver flags */ +} led_strip_rmt_config_t; + +/** + * @brief Create LED strip based on RMT TX channel + * + * @param led_config LED strip configuration + * @param rmt_config RMT specific configuration + * @param ret_strip Returned LED strip handle + * @return + * - ESP_OK: create LED strip handle successfully + * - ESP_ERR_INVALID_ARG: create LED strip handle failed because of invalid argument + * - ESP_ERR_NO_MEM: create LED strip handle failed because of out of memory + * - ESP_FAIL: create LED strip handle failed because some other error + */ +esp_err_t led_strip_new_rmt_device(const led_strip_config_t *led_config, const led_strip_rmt_config_t *rmt_config, led_strip_handle_t *ret_strip); + +#ifdef __cplusplus +} +#endif diff --git a/hw/bsp/espressif/components/led_strip/include/led_strip_spi.h b/hw/bsp/espressif/components/led_strip/include/led_strip_spi.h new file mode 100644 index 000000000..eb3524936 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/include/led_strip_spi.h @@ -0,0 +1,46 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include "esp_err.h" +#include "driver/spi_master.h" +#include "led_strip_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief LED Strip SPI specific configuration + */ +typedef struct { + spi_clock_source_t clk_src; /*!< SPI clock source */ + spi_host_device_t spi_bus; /*!< SPI bus ID. Which buses are available depends on the specific chip */ + struct { + uint32_t with_dma: 1; /*!< Use DMA to transmit data */ + } flags; /*!< Extra driver flags */ +} led_strip_spi_config_t; + +/** + * @brief Create LED strip based on SPI MOSI channel + * @note Although only the MOSI line is used for generating the signal, the whole SPI bus can't be used for other purposes. + * + * @param led_config LED strip configuration + * @param spi_config SPI specific configuration + * @param ret_strip Returned LED strip handle + * @return + * - ESP_OK: create LED strip handle successfully + * - ESP_ERR_INVALID_ARG: create LED strip handle failed because of invalid argument + * - ESP_ERR_NOT_SUPPORTED: create LED strip handle failed because of unsupported configuration + * - ESP_ERR_NO_MEM: create LED strip handle failed because of out of memory + * - ESP_FAIL: create LED strip handle failed because some other error + */ +esp_err_t led_strip_new_spi_device(const led_strip_config_t *led_config, const led_strip_spi_config_t *spi_config, led_strip_handle_t *ret_strip); + +#ifdef __cplusplus +} +#endif diff --git a/hw/bsp/espressif/components/led_strip/include/led_strip_types.h b/hw/bsp/espressif/components/led_strip/include/led_strip_types.h new file mode 100644 index 000000000..691f0bc39 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/include/led_strip_types.h @@ -0,0 +1,54 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief LED strip pixel format + */ +typedef enum { + LED_PIXEL_FORMAT_GRB, /*!< Pixel format: GRB */ + LED_PIXEL_FORMAT_GRBW, /*!< Pixel format: GRBW */ + LED_PIXEL_FORMAT_INVALID /*!< Invalid pixel format */ +} led_pixel_format_t; + +/** + * @brief LED strip model + * @note Different led model may have different timing parameters, so we need to distinguish them. + */ +typedef enum { + LED_MODEL_WS2812, /*!< LED strip model: WS2812 */ + LED_MODEL_SK6812, /*!< LED strip model: SK6812 */ + LED_MODEL_INVALID /*!< Invalid LED strip model */ +} led_model_t; + +/** + * @brief LED strip handle + */ +typedef struct led_strip_t *led_strip_handle_t; + +/** + * @brief LED Strip Configuration + */ +typedef struct { + int strip_gpio_num; /*!< GPIO number that used by LED strip */ + uint32_t max_leds; /*!< Maximum LEDs in a single strip */ + led_pixel_format_t led_pixel_format; /*!< LED pixel format */ + led_model_t led_model; /*!< LED model */ + + struct { + uint32_t invert_out: 1; /*!< Invert output signal */ + } flags; /*!< Extra driver flags */ +} led_strip_config_t; + +#ifdef __cplusplus +} +#endif diff --git a/hw/bsp/espressif/components/led_strip/interface/led_strip_interface.h b/hw/bsp/espressif/components/led_strip/interface/led_strip_interface.h new file mode 100644 index 000000000..3de4c2715 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/interface/led_strip_interface.h @@ -0,0 +1,95 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct led_strip_t led_strip_t; /*!< Type of LED strip */ + +/** + * @brief LED strip interface definition + */ +struct led_strip_t { + /** + * @brief Set RGB for a specific pixel + * + * @param strip: LED strip + * @param index: index of pixel to set + * @param red: red part of color + * @param green: green part of color + * @param blue: blue part of color + * + * @return + * - ESP_OK: Set RGB for a specific pixel successfully + * - ESP_ERR_INVALID_ARG: Set RGB for a specific pixel failed because of invalid parameters + * - ESP_FAIL: Set RGB for a specific pixel failed because other error occurred + */ + esp_err_t (*set_pixel)(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue); + + /** + * @brief Set RGBW for a specific pixel. Similar to `set_pixel` but also set the white component + * + * @param strip: LED strip + * @param index: index of pixel to set + * @param red: red part of color + * @param green: green part of color + * @param blue: blue part of color + * @param white: separate white component + * + * @return + * - ESP_OK: Set RGBW color for a specific pixel successfully + * - ESP_ERR_INVALID_ARG: Set RGBW color for a specific pixel failed because of an invalid argument + * - ESP_FAIL: Set RGBW color for a specific pixel failed because other error occurred + */ + esp_err_t (*set_pixel_rgbw)(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue, uint32_t white); + + /** + * @brief Refresh memory colors to LEDs + * + * @param strip: LED strip + * @param timeout_ms: timeout value for refreshing task + * + * @return + * - ESP_OK: Refresh successfully + * - ESP_FAIL: Refresh failed because some other error occurred + * + * @note: + * After updating the LED colors in the memory, a following invocation of this API is needed to flush colors to strip. + */ + esp_err_t (*refresh)(led_strip_t *strip); + + /** + * @brief Clear LED strip (turn off all LEDs) + * + * @param strip: LED strip + * @param timeout_ms: timeout value for clearing task + * + * @return + * - ESP_OK: Clear LEDs successfully + * - ESP_FAIL: Clear LEDs failed because some other error occurred + */ + esp_err_t (*clear)(led_strip_t *strip); + + /** + * @brief Free LED strip resources + * + * @param strip: LED strip + * + * @return + * - ESP_OK: Free resources successfully + * - ESP_FAIL: Free resources failed because error occurred + */ + esp_err_t (*del)(led_strip_t *strip); +}; + +#ifdef __cplusplus +} +#endif diff --git a/hw/bsp/espressif/components/led_strip/src/led_strip_api.c b/hw/bsp/espressif/components/led_strip/src/led_strip_api.c new file mode 100644 index 000000000..6eb86b8f1 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/src/led_strip_api.c @@ -0,0 +1,94 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "esp_log.h" +#include "esp_check.h" +#include "led_strip.h" +#include "led_strip_interface.h" + +static const char *TAG = "led_strip"; + +esp_err_t led_strip_set_pixel(led_strip_handle_t strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue) +{ + ESP_RETURN_ON_FALSE(strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + return strip->set_pixel(strip, index, red, green, blue); +} + +esp_err_t led_strip_set_pixel_hsv(led_strip_handle_t strip, uint32_t index, uint16_t hue, uint8_t saturation, uint8_t value) +{ + ESP_RETURN_ON_FALSE(strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + + uint32_t red = 0; + uint32_t green = 0; + uint32_t blue = 0; + + uint32_t rgb_max = value; + uint32_t rgb_min = rgb_max * (255 - saturation) / 255.0f; + + uint32_t i = hue / 60; + uint32_t diff = hue % 60; + + // RGB adjustment amount by hue + uint32_t rgb_adj = (rgb_max - rgb_min) * diff / 60; + + switch (i) { + case 0: + red = rgb_max; + green = rgb_min + rgb_adj; + blue = rgb_min; + break; + case 1: + red = rgb_max - rgb_adj; + green = rgb_max; + blue = rgb_min; + break; + case 2: + red = rgb_min; + green = rgb_max; + blue = rgb_min + rgb_adj; + break; + case 3: + red = rgb_min; + green = rgb_max - rgb_adj; + blue = rgb_max; + break; + case 4: + red = rgb_min + rgb_adj; + green = rgb_min; + blue = rgb_max; + break; + default: + red = rgb_max; + green = rgb_min; + blue = rgb_max - rgb_adj; + break; + } + + return strip->set_pixel(strip, index, red, green, blue); +} + +esp_err_t led_strip_set_pixel_rgbw(led_strip_handle_t strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue, uint32_t white) +{ + ESP_RETURN_ON_FALSE(strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + return strip->set_pixel_rgbw(strip, index, red, green, blue, white); +} + +esp_err_t led_strip_refresh(led_strip_handle_t strip) +{ + ESP_RETURN_ON_FALSE(strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + return strip->refresh(strip); +} + +esp_err_t led_strip_clear(led_strip_handle_t strip) +{ + ESP_RETURN_ON_FALSE(strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + return strip->clear(strip); +} + +esp_err_t led_strip_del(led_strip_handle_t strip) +{ + ESP_RETURN_ON_FALSE(strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + return strip->del(strip); +} diff --git a/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_dev.c b/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_dev.c new file mode 100644 index 000000000..1cbf0e45a --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_dev.c @@ -0,0 +1,164 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include "esp_log.h" +#include "esp_check.h" +#include "driver/rmt_tx.h" +#include "led_strip.h" +#include "led_strip_interface.h" +#include "led_strip_rmt_encoder.h" + +#define LED_STRIP_RMT_DEFAULT_RESOLUTION 10000000 // 10MHz resolution +#define LED_STRIP_RMT_DEFAULT_TRANS_QUEUE_SIZE 4 +// the memory size of each RMT channel, in words (4 bytes) +#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 +#define LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS 64 +#else +#define LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS 48 +#endif + +static const char *TAG = "led_strip_rmt"; + +typedef struct { + led_strip_t base; + rmt_channel_handle_t rmt_chan; + rmt_encoder_handle_t strip_encoder; + uint32_t strip_len; + uint8_t bytes_per_pixel; + uint8_t pixel_buf[]; +} led_strip_rmt_obj; + +static esp_err_t led_strip_rmt_set_pixel(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue) +{ + led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); + ESP_RETURN_ON_FALSE(index < rmt_strip->strip_len, ESP_ERR_INVALID_ARG, TAG, "index out of maximum number of LEDs"); + uint32_t start = index * rmt_strip->bytes_per_pixel; + // In thr order of GRB, as LED strip like WS2812 sends out pixels in this order + rmt_strip->pixel_buf[start + 0] = green & 0xFF; + rmt_strip->pixel_buf[start + 1] = red & 0xFF; + rmt_strip->pixel_buf[start + 2] = blue & 0xFF; + if (rmt_strip->bytes_per_pixel > 3) { + rmt_strip->pixel_buf[start + 3] = 0; + } + return ESP_OK; +} + +static esp_err_t led_strip_rmt_set_pixel_rgbw(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue, uint32_t white) +{ + led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); + ESP_RETURN_ON_FALSE(index < rmt_strip->strip_len, ESP_ERR_INVALID_ARG, TAG, "index out of maximum number of LEDs"); + ESP_RETURN_ON_FALSE(rmt_strip->bytes_per_pixel == 4, ESP_ERR_INVALID_ARG, TAG, "wrong LED pixel format, expected 4 bytes per pixel"); + uint8_t *buf_start = rmt_strip->pixel_buf + index * 4; + // SK6812 component order is GRBW + *buf_start = green & 0xFF; + *++buf_start = red & 0xFF; + *++buf_start = blue & 0xFF; + *++buf_start = white & 0xFF; + return ESP_OK; +} + +static esp_err_t led_strip_rmt_refresh(led_strip_t *strip) +{ + led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); + rmt_transmit_config_t tx_conf = { + .loop_count = 0, + }; + + ESP_RETURN_ON_ERROR(rmt_enable(rmt_strip->rmt_chan), TAG, "enable RMT channel failed"); + ESP_RETURN_ON_ERROR(rmt_transmit(rmt_strip->rmt_chan, rmt_strip->strip_encoder, rmt_strip->pixel_buf, + rmt_strip->strip_len * rmt_strip->bytes_per_pixel, &tx_conf), TAG, "transmit pixels by RMT failed"); + ESP_RETURN_ON_ERROR(rmt_tx_wait_all_done(rmt_strip->rmt_chan, -1), TAG, "flush RMT channel failed"); + ESP_RETURN_ON_ERROR(rmt_disable(rmt_strip->rmt_chan), TAG, "disable RMT channel failed"); + return ESP_OK; +} + +static esp_err_t led_strip_rmt_clear(led_strip_t *strip) +{ + led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); + // Write zero to turn off all leds + memset(rmt_strip->pixel_buf, 0, rmt_strip->strip_len * rmt_strip->bytes_per_pixel); + return led_strip_rmt_refresh(strip); +} + +static esp_err_t led_strip_rmt_del(led_strip_t *strip) +{ + led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); + ESP_RETURN_ON_ERROR(rmt_del_channel(rmt_strip->rmt_chan), TAG, "delete RMT channel failed"); + ESP_RETURN_ON_ERROR(rmt_del_encoder(rmt_strip->strip_encoder), TAG, "delete strip encoder failed"); + free(rmt_strip); + return ESP_OK; +} + +esp_err_t led_strip_new_rmt_device(const led_strip_config_t *led_config, const led_strip_rmt_config_t *rmt_config, led_strip_handle_t *ret_strip) +{ + led_strip_rmt_obj *rmt_strip = NULL; + esp_err_t ret = ESP_OK; + ESP_GOTO_ON_FALSE(led_config && rmt_config && ret_strip, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); + ESP_GOTO_ON_FALSE(led_config->led_pixel_format < LED_PIXEL_FORMAT_INVALID, ESP_ERR_INVALID_ARG, err, TAG, "invalid led_pixel_format"); + uint8_t bytes_per_pixel = 3; + if (led_config->led_pixel_format == LED_PIXEL_FORMAT_GRBW) { + bytes_per_pixel = 4; + } else if (led_config->led_pixel_format == LED_PIXEL_FORMAT_GRB) { + bytes_per_pixel = 3; + } else { + assert(false); + } + rmt_strip = calloc(1, sizeof(led_strip_rmt_obj) + led_config->max_leds * bytes_per_pixel); + ESP_GOTO_ON_FALSE(rmt_strip, ESP_ERR_NO_MEM, err, TAG, "no mem for rmt strip"); + uint32_t resolution = rmt_config->resolution_hz ? rmt_config->resolution_hz : LED_STRIP_RMT_DEFAULT_RESOLUTION; + + // for backward compatibility, if the user does not set the clk_src, use the default value + rmt_clock_source_t clk_src = RMT_CLK_SRC_DEFAULT; + if (rmt_config->clk_src) { + clk_src = rmt_config->clk_src; + } + size_t mem_block_symbols = LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS; + // override the default value if the user sets it + if (rmt_config->mem_block_symbols) { + mem_block_symbols = rmt_config->mem_block_symbols; + } + rmt_tx_channel_config_t rmt_chan_config = { + .clk_src = clk_src, + .gpio_num = led_config->strip_gpio_num, + .mem_block_symbols = mem_block_symbols, + .resolution_hz = resolution, + .trans_queue_depth = LED_STRIP_RMT_DEFAULT_TRANS_QUEUE_SIZE, + .flags.with_dma = rmt_config->flags.with_dma, + .flags.invert_out = led_config->flags.invert_out, + }; + ESP_GOTO_ON_ERROR(rmt_new_tx_channel(&rmt_chan_config, &rmt_strip->rmt_chan), err, TAG, "create RMT TX channel failed"); + + led_strip_encoder_config_t strip_encoder_conf = { + .resolution = resolution, + .led_model = led_config->led_model + }; + ESP_GOTO_ON_ERROR(rmt_new_led_strip_encoder(&strip_encoder_conf, &rmt_strip->strip_encoder), err, TAG, "create LED strip encoder failed"); + + + rmt_strip->bytes_per_pixel = bytes_per_pixel; + rmt_strip->strip_len = led_config->max_leds; + rmt_strip->base.set_pixel = led_strip_rmt_set_pixel; + rmt_strip->base.set_pixel_rgbw = led_strip_rmt_set_pixel_rgbw; + rmt_strip->base.refresh = led_strip_rmt_refresh; + rmt_strip->base.clear = led_strip_rmt_clear; + rmt_strip->base.del = led_strip_rmt_del; + + *ret_strip = &rmt_strip->base; + return ESP_OK; +err: + if (rmt_strip) { + if (rmt_strip->rmt_chan) { + rmt_del_channel(rmt_strip->rmt_chan); + } + if (rmt_strip->strip_encoder) { + rmt_del_encoder(rmt_strip->strip_encoder); + } + free(rmt_strip); + } + return ret; +} diff --git a/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_dev_idf4.c b/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_dev_idf4.c new file mode 100644 index 000000000..a1067cd7c --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_dev_idf4.c @@ -0,0 +1,194 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include "esp_log.h" +#include "esp_check.h" +#include "driver/rmt.h" +#include "led_strip.h" +#include "led_strip_interface.h" + +static const char *TAG = "led_strip_rmt"; + +#define WS2812_T0H_NS (300) +#define WS2812_T0L_NS (900) +#define WS2812_T1H_NS (900) +#define WS2812_T1L_NS (300) + +#define SK6812_T0H_NS (300) +#define SK6812_T0L_NS (900) +#define SK6812_T1H_NS (600) +#define SK6812_T1L_NS (600) + +#define LED_STRIP_RESET_MS (10) + +// the memory size of each RMT channel, in words (4 bytes) +#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 +#define LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS 64 +#else +#define LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS 48 +#endif + +static uint32_t led_t0h_ticks = 0; +static uint32_t led_t1h_ticks = 0; +static uint32_t led_t0l_ticks = 0; +static uint32_t led_t1l_ticks = 0; + +typedef struct { + led_strip_t base; + rmt_channel_t rmt_channel; + uint32_t strip_len; + uint8_t bytes_per_pixel; + uint8_t buffer[0]; +} led_strip_rmt_obj; + +static void IRAM_ATTR ws2812_rmt_adapter(const void *src, rmt_item32_t *dest, size_t src_size, + size_t wanted_num, size_t *translated_size, size_t *item_num) +{ + if (src == NULL || dest == NULL) { + *translated_size = 0; + *item_num = 0; + return; + } + const rmt_item32_t bit0 = {{{ led_t0h_ticks, 1, led_t0l_ticks, 0 }}}; //Logical 0 + const rmt_item32_t bit1 = {{{ led_t1h_ticks, 1, led_t1l_ticks, 0 }}}; //Logical 1 + size_t size = 0; + size_t num = 0; + uint8_t *psrc = (uint8_t *)src; + rmt_item32_t *pdest = dest; + while (size < src_size && num < wanted_num) { + for (int i = 0; i < 8; i++) { + // MSB first + if (*psrc & (1 << (7 - i))) { + pdest->val = bit1.val; + } else { + pdest->val = bit0.val; + } + num++; + pdest++; + } + size++; + psrc++; + } + *translated_size = size; + *item_num = num; +} + +static esp_err_t led_strip_rmt_set_pixel(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue) +{ + led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); + ESP_RETURN_ON_FALSE(index < rmt_strip->strip_len, ESP_ERR_INVALID_ARG, TAG, "index out of the maximum number of leds"); + uint32_t start = index * rmt_strip->bytes_per_pixel; + // In thr order of GRB + rmt_strip->buffer[start + 0] = green & 0xFF; + rmt_strip->buffer[start + 1] = red & 0xFF; + rmt_strip->buffer[start + 2] = blue & 0xFF; + if (rmt_strip->bytes_per_pixel > 3) { + rmt_strip->buffer[start + 3] = 0; + } + return ESP_OK; +} + +static esp_err_t led_strip_rmt_refresh(led_strip_t *strip) +{ + led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); + ESP_RETURN_ON_ERROR(rmt_write_sample(rmt_strip->rmt_channel, rmt_strip->buffer, rmt_strip->strip_len * rmt_strip->bytes_per_pixel, true), TAG, + "transmit RMT samples failed"); + vTaskDelay(pdMS_TO_TICKS(LED_STRIP_RESET_MS)); + return ESP_OK; +} + +static esp_err_t led_strip_rmt_clear(led_strip_t *strip) +{ + led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); + // Write zero to turn off all LEDs + memset(rmt_strip->buffer, 0, rmt_strip->strip_len * rmt_strip->bytes_per_pixel); + return led_strip_rmt_refresh(strip); +} + +static esp_err_t led_strip_rmt_del(led_strip_t *strip) +{ + led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); + ESP_RETURN_ON_ERROR(rmt_driver_uninstall(rmt_strip->rmt_channel), TAG, "uninstall RMT driver failed"); + free(rmt_strip); + return ESP_OK; +} + +esp_err_t led_strip_new_rmt_device(const led_strip_config_t *led_config, const led_strip_rmt_config_t *dev_config, led_strip_handle_t *ret_strip) +{ + led_strip_rmt_obj *rmt_strip = NULL; + esp_err_t ret = ESP_OK; + ESP_RETURN_ON_FALSE(led_config && dev_config && ret_strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + ESP_RETURN_ON_FALSE(led_config->led_pixel_format < LED_PIXEL_FORMAT_INVALID, ESP_ERR_INVALID_ARG, TAG, "invalid led_pixel_format"); + ESP_RETURN_ON_FALSE(dev_config->flags.with_dma == 0, ESP_ERR_NOT_SUPPORTED, TAG, "DMA is not supported"); + + uint8_t bytes_per_pixel = 3; + if (led_config->led_pixel_format == LED_PIXEL_FORMAT_GRBW) { + bytes_per_pixel = 4; + } else if (led_config->led_pixel_format == LED_PIXEL_FORMAT_GRB) { + bytes_per_pixel = 3; + } else { + assert(false); + } + + // allocate memory for led_strip object + rmt_strip = calloc(1, sizeof(led_strip_rmt_obj) + led_config->max_leds * bytes_per_pixel); + ESP_RETURN_ON_FALSE(rmt_strip, ESP_ERR_NO_MEM, TAG, "request memory for les_strip failed"); + + // install RMT channel driver + rmt_config_t config = RMT_DEFAULT_CONFIG_TX(led_config->strip_gpio_num, dev_config->rmt_channel); + // set the minimal clock division because the LED strip needs a high clock resolution + config.clk_div = 2; + + uint8_t mem_block_num = 2; + // override the default value if the user specify the mem block size + if (dev_config->mem_block_symbols) { + mem_block_num = (dev_config->mem_block_symbols + LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS / 2) / LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS; + } + config.mem_block_num = mem_block_num; + + ESP_GOTO_ON_ERROR(rmt_config(&config), err, TAG, "RMT config failed"); + ESP_GOTO_ON_ERROR(rmt_driver_install(config.channel, 0, 0), err, TAG, "RMT install failed"); + + uint32_t counter_clk_hz = 0; + rmt_get_counter_clock((rmt_channel_t)dev_config->rmt_channel, &counter_clk_hz); + // ns -> ticks + float ratio = (float)counter_clk_hz / 1e9; + if (led_config->led_model == LED_MODEL_WS2812) { + led_t0h_ticks = (uint32_t)(ratio * WS2812_T0H_NS); + led_t0l_ticks = (uint32_t)(ratio * WS2812_T0L_NS); + led_t1h_ticks = (uint32_t)(ratio * WS2812_T1H_NS); + led_t1l_ticks = (uint32_t)(ratio * WS2812_T1L_NS); + } else if (led_config->led_model == LED_MODEL_SK6812) { + led_t0h_ticks = (uint32_t)(ratio * SK6812_T0H_NS); + led_t0l_ticks = (uint32_t)(ratio * SK6812_T0L_NS); + led_t1h_ticks = (uint32_t)(ratio * SK6812_T1H_NS); + led_t1l_ticks = (uint32_t)(ratio * SK6812_T1L_NS); + } else { + assert(false); + } + + // adapter to translates the LES strip date frame into RMT symbols + rmt_translator_init((rmt_channel_t)dev_config->rmt_channel, ws2812_rmt_adapter); + + rmt_strip->bytes_per_pixel = bytes_per_pixel; + rmt_strip->rmt_channel = (rmt_channel_t)dev_config->rmt_channel; + rmt_strip->strip_len = led_config->max_leds; + rmt_strip->base.set_pixel = led_strip_rmt_set_pixel; + rmt_strip->base.refresh = led_strip_rmt_refresh; + rmt_strip->base.clear = led_strip_rmt_clear; + rmt_strip->base.del = led_strip_rmt_del; + + *ret_strip = &rmt_strip->base; + return ESP_OK; + +err: + if (rmt_strip) { + free(rmt_strip); + } + return ret; +} diff --git a/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_encoder.c b/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_encoder.c new file mode 100644 index 000000000..d352ac07f --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_encoder.c @@ -0,0 +1,146 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_check.h" +#include "led_strip_rmt_encoder.h" + +static const char *TAG = "led_rmt_encoder"; + +typedef struct { + rmt_encoder_t base; + rmt_encoder_t *bytes_encoder; + rmt_encoder_t *copy_encoder; + int state; + rmt_symbol_word_t reset_code; +} rmt_led_strip_encoder_t; + +static size_t rmt_encode_led_strip(rmt_encoder_t *encoder, rmt_channel_handle_t channel, const void *primary_data, size_t data_size, rmt_encode_state_t *ret_state) +{ + rmt_led_strip_encoder_t *led_encoder = __containerof(encoder, rmt_led_strip_encoder_t, base); + rmt_encoder_handle_t bytes_encoder = led_encoder->bytes_encoder; + rmt_encoder_handle_t copy_encoder = led_encoder->copy_encoder; + rmt_encode_state_t session_state = 0; + rmt_encode_state_t state = 0; + size_t encoded_symbols = 0; + switch (led_encoder->state) { + case 0: // send RGB data + encoded_symbols += bytes_encoder->encode(bytes_encoder, channel, primary_data, data_size, &session_state); + if (session_state & RMT_ENCODING_COMPLETE) { + led_encoder->state = 1; // switch to next state when current encoding session finished + } + if (session_state & RMT_ENCODING_MEM_FULL) { + state |= RMT_ENCODING_MEM_FULL; + goto out; // yield if there's no free space for encoding artifacts + } + // fall-through + case 1: // send reset code + encoded_symbols += copy_encoder->encode(copy_encoder, channel, &led_encoder->reset_code, + sizeof(led_encoder->reset_code), &session_state); + if (session_state & RMT_ENCODING_COMPLETE) { + led_encoder->state = 0; // back to the initial encoding session + state |= RMT_ENCODING_COMPLETE; + } + if (session_state & RMT_ENCODING_MEM_FULL) { + state |= RMT_ENCODING_MEM_FULL; + goto out; // yield if there's no free space for encoding artifacts + } + } +out: + *ret_state = state; + return encoded_symbols; +} + +static esp_err_t rmt_del_led_strip_encoder(rmt_encoder_t *encoder) +{ + rmt_led_strip_encoder_t *led_encoder = __containerof(encoder, rmt_led_strip_encoder_t, base); + rmt_del_encoder(led_encoder->bytes_encoder); + rmt_del_encoder(led_encoder->copy_encoder); + free(led_encoder); + return ESP_OK; +} + +static esp_err_t rmt_led_strip_encoder_reset(rmt_encoder_t *encoder) +{ + rmt_led_strip_encoder_t *led_encoder = __containerof(encoder, rmt_led_strip_encoder_t, base); + rmt_encoder_reset(led_encoder->bytes_encoder); + rmt_encoder_reset(led_encoder->copy_encoder); + led_encoder->state = 0; + return ESP_OK; +} + +esp_err_t rmt_new_led_strip_encoder(const led_strip_encoder_config_t *config, rmt_encoder_handle_t *ret_encoder) +{ + esp_err_t ret = ESP_OK; + rmt_led_strip_encoder_t *led_encoder = NULL; + ESP_GOTO_ON_FALSE(config && ret_encoder, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); + ESP_GOTO_ON_FALSE(config->led_model < LED_MODEL_INVALID, ESP_ERR_INVALID_ARG, err, TAG, "invalid led model"); + led_encoder = calloc(1, sizeof(rmt_led_strip_encoder_t)); + ESP_GOTO_ON_FALSE(led_encoder, ESP_ERR_NO_MEM, err, TAG, "no mem for led strip encoder"); + led_encoder->base.encode = rmt_encode_led_strip; + led_encoder->base.del = rmt_del_led_strip_encoder; + led_encoder->base.reset = rmt_led_strip_encoder_reset; + rmt_bytes_encoder_config_t bytes_encoder_config; + if (config->led_model == LED_MODEL_SK6812) { + bytes_encoder_config = (rmt_bytes_encoder_config_t) { + .bit0 = { + .level0 = 1, + .duration0 = 0.3 * config->resolution / 1000000, // T0H=0.3us + .level1 = 0, + .duration1 = 0.9 * config->resolution / 1000000, // T0L=0.9us + }, + .bit1 = { + .level0 = 1, + .duration0 = 0.6 * config->resolution / 1000000, // T1H=0.6us + .level1 = 0, + .duration1 = 0.6 * config->resolution / 1000000, // T1L=0.6us + }, + .flags.msb_first = 1 // SK6812 transfer bit order: G7...G0R7...R0B7...B0(W7...W0) + }; + } else if (config->led_model == LED_MODEL_WS2812) { + // different led strip might have its own timing requirements, following parameter is for WS2812 + bytes_encoder_config = (rmt_bytes_encoder_config_t) { + .bit0 = { + .level0 = 1, + .duration0 = 0.3 * config->resolution / 1000000, // T0H=0.3us + .level1 = 0, + .duration1 = 0.9 * config->resolution / 1000000, // T0L=0.9us + }, + .bit1 = { + .level0 = 1, + .duration0 = 0.9 * config->resolution / 1000000, // T1H=0.9us + .level1 = 0, + .duration1 = 0.3 * config->resolution / 1000000, // T1L=0.3us + }, + .flags.msb_first = 1 // WS2812 transfer bit order: G7...G0R7...R0B7...B0 + }; + } else { + assert(false); + } + ESP_GOTO_ON_ERROR(rmt_new_bytes_encoder(&bytes_encoder_config, &led_encoder->bytes_encoder), err, TAG, "create bytes encoder failed"); + rmt_copy_encoder_config_t copy_encoder_config = {}; + ESP_GOTO_ON_ERROR(rmt_new_copy_encoder(©_encoder_config, &led_encoder->copy_encoder), err, TAG, "create copy encoder failed"); + + uint32_t reset_ticks = config->resolution / 1000000 * 50 / 2; // reset code duration defaults to 50us + led_encoder->reset_code = (rmt_symbol_word_t) { + .level0 = 0, + .duration0 = reset_ticks, + .level1 = 0, + .duration1 = reset_ticks, + }; + *ret_encoder = &led_encoder->base; + return ESP_OK; +err: + if (led_encoder) { + if (led_encoder->bytes_encoder) { + rmt_del_encoder(led_encoder->bytes_encoder); + } + if (led_encoder->copy_encoder) { + rmt_del_encoder(led_encoder->copy_encoder); + } + free(led_encoder); + } + return ret; +} diff --git a/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_encoder.h b/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_encoder.h new file mode 100644 index 000000000..ba71e60ab --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_encoder.h @@ -0,0 +1,38 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include "driver/rmt_encoder.h" +#include "led_strip_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Type of led strip encoder configuration + */ +typedef struct { + uint32_t resolution; /*!< Encoder resolution, in Hz */ + led_model_t led_model; /*!< LED model */ +} led_strip_encoder_config_t; + +/** + * @brief Create RMT encoder for encoding LED strip pixels into RMT symbols + * + * @param[in] config Encoder configuration + * @param[out] ret_encoder Returned encoder handle + * @return + * - ESP_ERR_INVALID_ARG for any invalid arguments + * - ESP_ERR_NO_MEM out of memory when creating led strip encoder + * - ESP_OK if creating encoder successfully + */ +esp_err_t rmt_new_led_strip_encoder(const led_strip_encoder_config_t *config, rmt_encoder_handle_t *ret_encoder); + +#ifdef __cplusplus +} +#endif diff --git a/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_ws2812.c b/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_ws2812.c deleted file mode 100644 index fd1746cad..000000000 --- a/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_ws2812.c +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright 2019 Espressif Systems (Shanghai) PTE LTD -// -// 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. -#include -#include -#include -#include "esp_log.h" -#include "esp_attr.h" -#include "led_strip.h" -#include "driver/rmt.h" - -static const char *TAG = "ws2812"; -#define STRIP_CHECK(a, str, goto_tag, ret_value, ...) \ - do \ - { \ - if (!(a)) \ - { \ - ESP_LOGE(TAG, "%s(%d): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ - ret = ret_value; \ - goto goto_tag; \ - } \ - } while (0) - -#define WS2812_T0H_NS (350) -#define WS2812_T0L_NS (1000) -#define WS2812_T1H_NS (1000) -#define WS2812_T1L_NS (350) -#define WS2812_RESET_US (280) - -static uint32_t ws2812_t0h_ticks = 0; -static uint32_t ws2812_t1h_ticks = 0; -static uint32_t ws2812_t0l_ticks = 0; -static uint32_t ws2812_t1l_ticks = 0; - -typedef struct { - led_strip_t parent; - rmt_channel_t rmt_channel; - uint32_t strip_len; - uint8_t buffer[0]; -} ws2812_t; - -/** - * @brief Convert RGB data to RMT format. - * - * @note For WS2812, R,G,B each contains 256 different choices (i.e. uint8_t) - * - * @param[in] src: source data, to converted to RMT format - * @param[in] dest: place where to store the convert result - * @param[in] src_size: size of source data - * @param[in] wanted_num: number of RMT items that want to get - * @param[out] translated_size: number of source data that got converted - * @param[out] item_num: number of RMT items which are converted from source data - */ -static void IRAM_ATTR ws2812_rmt_adapter(const void *src, rmt_item32_t *dest, size_t src_size, - size_t wanted_num, size_t *translated_size, size_t *item_num) -{ - if (src == NULL || dest == NULL) { - *translated_size = 0; - *item_num = 0; - return; - } - const rmt_item32_t bit0 = {{{ ws2812_t0h_ticks, 1, ws2812_t0l_ticks, 0 }}}; //Logical 0 - const rmt_item32_t bit1 = {{{ ws2812_t1h_ticks, 1, ws2812_t1l_ticks, 0 }}}; //Logical 1 - size_t size = 0; - size_t num = 0; - uint8_t *psrc = (uint8_t *)src; - rmt_item32_t *pdest = dest; - while (size < src_size && num < wanted_num) { - for (int i = 0; i < 8; i++) { - // MSB first - if (*psrc & (1 << (7 - i))) { - pdest->val = bit1.val; - } else { - pdest->val = bit0.val; - } - num++; - pdest++; - } - size++; - psrc++; - } - *translated_size = size; - *item_num = num; -} - -static esp_err_t ws2812_set_pixel(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue) -{ - esp_err_t ret = ESP_OK; - ws2812_t *ws2812 = __containerof(strip, ws2812_t, parent); - STRIP_CHECK(index < ws2812->strip_len, "index out of the maximum number of leds", err, ESP_ERR_INVALID_ARG); - uint32_t start = index * 3; - // In thr order of GRB - ws2812->buffer[start + 0] = green & 0xFF; - ws2812->buffer[start + 1] = red & 0xFF; - ws2812->buffer[start + 2] = blue & 0xFF; - return ESP_OK; -err: - return ret; -} - -static esp_err_t ws2812_refresh(led_strip_t *strip, uint32_t timeout_ms) -{ - esp_err_t ret = ESP_OK; - ws2812_t *ws2812 = __containerof(strip, ws2812_t, parent); - STRIP_CHECK(rmt_write_sample(ws2812->rmt_channel, ws2812->buffer, ws2812->strip_len * 3, true) == ESP_OK, - "transmit RMT samples failed", err, ESP_FAIL); - return rmt_wait_tx_done(ws2812->rmt_channel, pdMS_TO_TICKS(timeout_ms)); -err: - return ret; -} - -static esp_err_t ws2812_clear(led_strip_t *strip, uint32_t timeout_ms) -{ - ws2812_t *ws2812 = __containerof(strip, ws2812_t, parent); - // Write zero to turn off all leds - memset(ws2812->buffer, 0, ws2812->strip_len * 3); - return ws2812_refresh(strip, timeout_ms); -} - -static esp_err_t ws2812_del(led_strip_t *strip) -{ - ws2812_t *ws2812 = __containerof(strip, ws2812_t, parent); - free(ws2812); - return ESP_OK; -} - -led_strip_t *led_strip_new_rmt_ws2812(const led_strip_config_t *config) -{ - led_strip_t *ret = NULL; - STRIP_CHECK(config, "configuration can't be null", err, NULL); - - // 24 bits per led - uint32_t ws2812_size = sizeof(ws2812_t) + config->max_leds * 3; - ws2812_t *ws2812 = calloc(1, ws2812_size); - STRIP_CHECK(ws2812, "request memory for ws2812 failed", err, NULL); - - uint32_t counter_clk_hz = 0; - STRIP_CHECK(rmt_get_counter_clock((rmt_channel_t)config->dev, &counter_clk_hz) == ESP_OK, - "get rmt counter clock failed", err, NULL); - // ns -> ticks - float ratio = (float)counter_clk_hz / 1e9; - ws2812_t0h_ticks = (uint32_t)(ratio * WS2812_T0H_NS); - ws2812_t0l_ticks = (uint32_t)(ratio * WS2812_T0L_NS); - ws2812_t1h_ticks = (uint32_t)(ratio * WS2812_T1H_NS); - ws2812_t1l_ticks = (uint32_t)(ratio * WS2812_T1L_NS); - - // set ws2812 to rmt adapter - rmt_translator_init((rmt_channel_t)config->dev, ws2812_rmt_adapter); - - ws2812->rmt_channel = (rmt_channel_t)config->dev; - ws2812->strip_len = config->max_leds; - - ws2812->parent.set_pixel = ws2812_set_pixel; - ws2812->parent.refresh = ws2812_refresh; - ws2812->parent.clear = ws2812_clear; - ws2812->parent.del = ws2812_del; - - return &ws2812->parent; -err: - return ret; -} diff --git a/hw/bsp/espressif/components/led_strip/src/led_strip_spi_dev.c b/hw/bsp/espressif/components/led_strip/src/led_strip_spi_dev.c new file mode 100644 index 000000000..12ea8fbf3 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/src/led_strip_spi_dev.c @@ -0,0 +1,209 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include "esp_log.h" +#include "esp_check.h" +#include "esp_rom_gpio.h" +#include "soc/spi_periph.h" +#include "led_strip.h" +#include "led_strip_interface.h" +#include "hal/spi_hal.h" + +#define LED_STRIP_SPI_DEFAULT_RESOLUTION (2.5 * 1000 * 1000) // 2.5MHz resolution +#define LED_STRIP_SPI_DEFAULT_TRANS_QUEUE_SIZE 4 + +#define SPI_BYTES_PER_COLOR_BYTE 3 +#define SPI_BITS_PER_COLOR_BYTE (SPI_BYTES_PER_COLOR_BYTE * 8) + +static const char *TAG = "led_strip_spi"; + +typedef struct { + led_strip_t base; + spi_host_device_t spi_host; + spi_device_handle_t spi_device; + uint32_t strip_len; + uint8_t bytes_per_pixel; + uint8_t pixel_buf[]; +} led_strip_spi_obj; + +// please make sure to zero-initialize the buf before calling this function +static void __led_strip_spi_bit(uint8_t data, uint8_t *buf) +{ + // Each color of 1 bit is represented by 3 bits of SPI, low_level:100 ,high_level:110 + // So a color byte occupies 3 bytes of SPI. + *(buf + 2) |= data & BIT(0) ? BIT(2) | BIT(1) : BIT(2); + *(buf + 2) |= data & BIT(1) ? BIT(5) | BIT(4) : BIT(5); + *(buf + 2) |= data & BIT(2) ? BIT(7) : 0x00; + *(buf + 1) |= BIT(0); + *(buf + 1) |= data & BIT(3) ? BIT(3) | BIT(2) : BIT(3); + *(buf + 1) |= data & BIT(4) ? BIT(6) | BIT(5) : BIT(6); + *(buf + 0) |= data & BIT(5) ? BIT(1) | BIT(0) : BIT(1); + *(buf + 0) |= data & BIT(6) ? BIT(4) | BIT(3) : BIT(4); + *(buf + 0) |= data & BIT(7) ? BIT(7) | BIT(6) : BIT(7); +} + +static esp_err_t led_strip_spi_set_pixel(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue) +{ + led_strip_spi_obj *spi_strip = __containerof(strip, led_strip_spi_obj, base); + ESP_RETURN_ON_FALSE(index < spi_strip->strip_len, ESP_ERR_INVALID_ARG, TAG, "index out of maximum number of LEDs"); + // LED_PIXEL_FORMAT_GRB takes 72bits(9bytes) + uint32_t start = index * spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE; + memset(spi_strip->pixel_buf + start, 0, spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE); + __led_strip_spi_bit(green, &spi_strip->pixel_buf[start]); + __led_strip_spi_bit(red, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE]); + __led_strip_spi_bit(blue, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * 2]); + if (spi_strip->bytes_per_pixel > 3) { + __led_strip_spi_bit(0, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * 3]); + } + return ESP_OK; +} + +static esp_err_t led_strip_spi_set_pixel_rgbw(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue, uint32_t white) +{ + led_strip_spi_obj *spi_strip = __containerof(strip, led_strip_spi_obj, base); + ESP_RETURN_ON_FALSE(index < spi_strip->strip_len, ESP_ERR_INVALID_ARG, TAG, "index out of maximum number of LEDs"); + ESP_RETURN_ON_FALSE(spi_strip->bytes_per_pixel == 4, ESP_ERR_INVALID_ARG, TAG, "wrong LED pixel format, expected 4 bytes per pixel"); + // LED_PIXEL_FORMAT_GRBW takes 96bits(12bytes) + uint32_t start = index * spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE; + // SK6812 component order is GRBW + memset(spi_strip->pixel_buf + start, 0, spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE); + __led_strip_spi_bit(green, &spi_strip->pixel_buf[start]); + __led_strip_spi_bit(red, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE]); + __led_strip_spi_bit(blue, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * 2]); + __led_strip_spi_bit(white, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * 3]); + + return ESP_OK; +} + +static esp_err_t led_strip_spi_refresh(led_strip_t *strip) +{ + led_strip_spi_obj *spi_strip = __containerof(strip, led_strip_spi_obj, base); + spi_transaction_t tx_conf; + memset(&tx_conf, 0, sizeof(tx_conf)); + + tx_conf.length = spi_strip->strip_len * spi_strip->bytes_per_pixel * SPI_BITS_PER_COLOR_BYTE; + tx_conf.tx_buffer = spi_strip->pixel_buf; + tx_conf.rx_buffer = NULL; + ESP_RETURN_ON_ERROR(spi_device_transmit(spi_strip->spi_device, &tx_conf), TAG, "transmit pixels by SPI failed"); + + return ESP_OK; +} + +static esp_err_t led_strip_spi_clear(led_strip_t *strip) +{ + led_strip_spi_obj *spi_strip = __containerof(strip, led_strip_spi_obj, base); + //Write zero to turn off all leds + memset(spi_strip->pixel_buf, 0, spi_strip->strip_len * spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE); + uint8_t *buf = spi_strip->pixel_buf; + for (int index = 0; index < spi_strip->strip_len * spi_strip->bytes_per_pixel; index++) { + __led_strip_spi_bit(0, buf); + buf += SPI_BYTES_PER_COLOR_BYTE; + } + + return led_strip_spi_refresh(strip); +} + +static esp_err_t led_strip_spi_del(led_strip_t *strip) +{ + led_strip_spi_obj *spi_strip = __containerof(strip, led_strip_spi_obj, base); + + ESP_RETURN_ON_ERROR(spi_bus_remove_device(spi_strip->spi_device), TAG, "delete spi device failed"); + ESP_RETURN_ON_ERROR(spi_bus_free(spi_strip->spi_host), TAG, "free spi bus failed"); + + free(spi_strip); + return ESP_OK; +} + +esp_err_t led_strip_new_spi_device(const led_strip_config_t *led_config, const led_strip_spi_config_t *spi_config, led_strip_handle_t *ret_strip) +{ + led_strip_spi_obj *spi_strip = NULL; + esp_err_t ret = ESP_OK; + ESP_GOTO_ON_FALSE(led_config && spi_config && ret_strip, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); + ESP_GOTO_ON_FALSE(led_config->led_pixel_format < LED_PIXEL_FORMAT_INVALID, ESP_ERR_INVALID_ARG, err, TAG, "invalid led_pixel_format"); + uint8_t bytes_per_pixel = 3; + if (led_config->led_pixel_format == LED_PIXEL_FORMAT_GRBW) { + bytes_per_pixel = 4; + } else if (led_config->led_pixel_format == LED_PIXEL_FORMAT_GRB) { + bytes_per_pixel = 3; + } else { + assert(false); + } + uint32_t mem_caps = MALLOC_CAP_DEFAULT; + if (spi_config->flags.with_dma) { + // DMA buffer must be placed in internal SRAM + mem_caps |= MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA; + } + spi_strip = heap_caps_calloc(1, sizeof(led_strip_spi_obj) + led_config->max_leds * bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE, mem_caps); + + ESP_GOTO_ON_FALSE(spi_strip, ESP_ERR_NO_MEM, err, TAG, "no mem for spi strip"); + + spi_strip->spi_host = spi_config->spi_bus; + // for backward compatibility, if the user does not set the clk_src, use the default value + spi_clock_source_t clk_src = SPI_CLK_SRC_DEFAULT; + if (spi_config->clk_src) { + clk_src = spi_config->clk_src; + } + + spi_bus_config_t spi_bus_cfg = { + .mosi_io_num = led_config->strip_gpio_num, + //Only use MOSI to generate the signal, set -1 when other pins are not used. + .miso_io_num = -1, + .sclk_io_num = -1, + .quadwp_io_num = -1, + .quadhd_io_num = -1, + .max_transfer_sz = led_config->max_leds * bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE, + }; + ESP_GOTO_ON_ERROR(spi_bus_initialize(spi_strip->spi_host, &spi_bus_cfg, spi_config->flags.with_dma ? SPI_DMA_CH_AUTO : SPI_DMA_DISABLED), err, TAG, "create SPI bus failed"); + + if (led_config->flags.invert_out == true) { + esp_rom_gpio_connect_out_signal(led_config->strip_gpio_num, spi_periph_signal[spi_strip->spi_host].spid_out, true, false); + } + + spi_device_interface_config_t spi_dev_cfg = { + .clock_source = clk_src, + .command_bits = 0, + .address_bits = 0, + .dummy_bits = 0, + .clock_speed_hz = LED_STRIP_SPI_DEFAULT_RESOLUTION, + .mode = 0, + //set -1 when CS is not used + .spics_io_num = -1, + .queue_size = LED_STRIP_SPI_DEFAULT_TRANS_QUEUE_SIZE, + }; + + ESP_GOTO_ON_ERROR(spi_bus_add_device(spi_strip->spi_host, &spi_dev_cfg, &spi_strip->spi_device), err, TAG, "Failed to add spi device"); + + int clock_resolution_khz = 0; + spi_device_get_actual_freq(spi_strip->spi_device, &clock_resolution_khz); + // TODO: ideally we should decide the SPI_BYTES_PER_COLOR_BYTE by the real clock resolution + // But now, let's fixed the resolution, the downside is, we don't support a clock source whose frequency is not multiple of LED_STRIP_SPI_DEFAULT_RESOLUTION + ESP_GOTO_ON_FALSE(clock_resolution_khz == LED_STRIP_SPI_DEFAULT_RESOLUTION / 1000, ESP_ERR_NOT_SUPPORTED, err, + TAG, "unsupported clock resolution:%dKHz", clock_resolution_khz); + + spi_strip->bytes_per_pixel = bytes_per_pixel; + spi_strip->strip_len = led_config->max_leds; + spi_strip->base.set_pixel = led_strip_spi_set_pixel; + spi_strip->base.set_pixel_rgbw = led_strip_spi_set_pixel_rgbw; + spi_strip->base.refresh = led_strip_spi_refresh; + spi_strip->base.clear = led_strip_spi_clear; + spi_strip->base.del = led_strip_spi_del; + + *ret_strip = &spi_strip->base; + return ESP_OK; +err: + if (spi_strip) { + if (spi_strip->spi_device) { + spi_bus_remove_device(spi_strip->spi_device); + } + if (spi_strip->spi_host) { + spi_bus_free(spi_strip->spi_host); + } + free(spi_strip); + } + return ret; +} From e784e20b93068f4b063e066eb50ea005aeec99f4 Mon Sep 17 00:00:00 2001 From: IngHK Date: Wed, 7 Feb 2024 10:11:28 +0100 Subject: [PATCH 094/454] changes after review --- src/host/usbh.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/host/usbh.c b/src/host/usbh.c index ee7424ed9..d4f308e48 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -291,9 +291,6 @@ bool tuh_vid_pid_get(uint8_t dev_addr, uint16_t *vid, uint16_t *pid) { *vid = dev->vid; *pid = dev->pid; - TU_LOG_HEX_USBH(*vid); - TU_LOG_HEX_USBH(*pid); - return true; } @@ -863,7 +860,7 @@ bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * b // HCD error, mark endpoint as ready to allow next transfer ep_state->busy = 0; ep_state->claimed = 0; - TU_LOG_USBH("Failed\r\n"); + TU_LOG1("Failed\r\n"); // TU_BREAKPOINT(); return false; } @@ -1321,7 +1318,7 @@ static void process_enumeration(tuh_xfer_t* xfer) { if ( retry ) { failed_count++; osal_task_delay(ATTEMPT_DELAY_MS); // delay a bit - TU_LOG_USBH("Enumeration attempt %u\r\n", failed_count); + TU_LOG1("Enumeration attempt %u\r\n", failed_count); retry = tuh_control_xfer(xfer); } From 0531027b57e9401d49afa13e70f5a6a9763a3b85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20V=C3=A1zquez=20Blanco?= Date: Mon, 22 Jan 2024 23:19:43 +0100 Subject: [PATCH 095/454] usbd: log outbound xfer bytes in debug --- src/device/usbd.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/device/usbd.c b/src/device/usbd.c index 5c94ebcc5..28eb9aa6e 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -1232,6 +1232,11 @@ bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t // TU_VERIFY(tud_ready()); TU_LOG_USBD(" Queue EP %02X with %u bytes ...\r\n", ep_addr, total_bytes); +#if CFG_TUD_LOG_LEVEL >= 3 + if(tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { + TU_LOG_MEM(CFG_TUD_LOG_LEVEL, buffer, total_bytes, 2); + } +#endif // Attempt to transfer on a busy endpoint, sound like an race condition ! TU_ASSERT(_usbd_dev.ep_status[epnum][dir].busy == 0); From 6c4a5292a6a59dec1b7f37be42725ea85205f3c9 Mon Sep 17 00:00:00 2001 From: Jerry Palacios Date: Wed, 7 Feb 2024 17:03:13 -0600 Subject: [PATCH 096/454] Back to original --- .github/workflows/build_aarch64.yml | 2 +- .github/workflows/build_arm.yml | 2 +- .github/workflows/build_esp.yml | 6 +- .github/workflows/build_iar.yml | 2 + .github/workflows/build_msp430.yml | 2 +- .github/workflows/build_renesas.yml | 2 +- .github/workflows/build_riscv.yml | 2 +- .github/workflows/build_win_mac.yml | 2 +- .github/workflows/cmake_arm.yml | 4 +- .github/workflows/pre-commit.yml | 2 +- .../device/video_capture/src/CMakeLists.txt | 4 + examples/device/video_capture/src/images.h | 3 + examples/device/video_capture/src/main.c | 228 +++-- .../device/video_capture/src/tusb_config.h | 12 +- .../video_capture/src/usb_descriptors.c | 450 ++++++--- .../video_capture/src/usb_descriptors.h | 87 +- examples/host/cdc_msc_hid/src/cdc_app.c | 76 +- examples/host/cdc_msc_hid/src/tusb_config.h | 1 + .../cdc_msc_hid_freertos/src/tusb_config.h | 1 + hw/bsp/board_api.h | 19 +- hw/bsp/espressif/boards/family.c | 30 +- .../components/led_strip/CHANGELOG.md | 38 + .../components/led_strip/CMakeLists.txt | 27 +- hw/bsp/espressif/components/led_strip/LICENSE | 202 ++++ .../espressif/components/led_strip/README.md | 97 ++ hw/bsp/espressif/components/led_strip/api.md | 454 +++++++++ .../led_strip_rmt_ws2812/CMakeLists.txt | 9 + .../examples/led_strip_rmt_ws2812/README.md | 31 + .../led_strip_rmt_ws2812/dependencies.lock | 15 + .../led_strip_rmt_ws2812/main/CMakeLists.txt | 2 + .../main/idf_component.yml | 5 + .../main/led_strip_rmt_ws2812_main.c | 75 ++ .../components/led_strip/idf_component.yml | 5 + .../components/led_strip/include/led_strip.h | 207 ++-- .../led_strip/include/led_strip_rmt.h | 53 + .../led_strip/include/led_strip_spi.h | 46 + .../led_strip/include/led_strip_types.h | 54 + .../led_strip/interface/led_strip_interface.h | 95 ++ .../components/led_strip/src/led_strip_api.c | 94 ++ .../led_strip/src/led_strip_rmt_dev.c | 164 ++++ .../led_strip/src/led_strip_rmt_dev_idf4.c | 194 ++++ .../led_strip/src/led_strip_rmt_encoder.c | 146 +++ .../led_strip/src/led_strip_rmt_encoder.h | 38 + .../led_strip/src/led_strip_rmt_ws2812.c | 171 ---- .../led_strip/src/led_strip_spi_dev.c | 209 ++++ hw/bsp/family_support.cmake | 1 - hw/bsp/mcx/boards/bunny-brain/board.cmake | 21 - hw/bsp/mcx/boards/bunny-brain/board.h | 66 -- hw/bsp/mcx/boards/bunny-brain/board.mk | 11 - hw/bsp/mcx/boards/bunny-brain/clock_config.c | 338 ------- hw/bsp/mcx/boards/bunny-brain/clock_config.h | 177 ---- hw/bsp/mcx/boards/bunny-brain/pin_mux.c | 141 --- hw/bsp/mcx/boards/bunny-brain/pin_mux.h | 51 - hw/bsp/mcx/boards/frdm-mcxn947/board.cmake | 21 - hw/bsp/mcx/boards/frdm-mcxn947/board.h | 66 -- hw/bsp/mcx/boards/frdm-mcxn947/board.mk | 11 - hw/bsp/mcx/boards/frdm-mcxn947/clock_config.c | 338 ------- hw/bsp/mcx/boards/frdm-mcxn947/clock_config.h | 177 ---- hw/bsp/mcx/boards/frdm-mcxn947/pin_mux.c | 143 --- hw/bsp/mcx/boards/frdm-mcxn947/pin_mux.h | 51 - src/class/audio/audio_device.c | 2 +- src/class/cdc/cdc.h | 20 +- src/class/cdc/cdc_host.c | 920 +++++++++++++----- src/class/cdc/cdc_host.h | 13 +- src/class/cdc/serial/ch34x.h | 84 ++ src/class/hid/hid_host.c | 6 +- src/class/vendor/vendor_device.c | 8 +- src/class/video/video.h | 242 +++-- src/class/video/video_device.c | 26 +- src/common/tusb_common.h | 1 + src/common/tusb_types.h | 157 ++- src/portable/synopsys/dwc2/dcd_dwc2.c | 4 +- src/tusb_option.h | 17 + test/hil/hil_test.py | 11 +- 74 files changed, 3852 insertions(+), 2640 deletions(-) create mode 100644 examples/device/video_capture/src/CMakeLists.txt create mode 100644 hw/bsp/espressif/components/led_strip/CHANGELOG.md create mode 100644 hw/bsp/espressif/components/led_strip/LICENSE create mode 100644 hw/bsp/espressif/components/led_strip/README.md create mode 100644 hw/bsp/espressif/components/led_strip/api.md create mode 100644 hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/CMakeLists.txt create mode 100644 hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/README.md create mode 100644 hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/dependencies.lock create mode 100644 hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/main/CMakeLists.txt create mode 100644 hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/main/idf_component.yml create mode 100644 hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/main/led_strip_rmt_ws2812_main.c create mode 100644 hw/bsp/espressif/components/led_strip/idf_component.yml create mode 100644 hw/bsp/espressif/components/led_strip/include/led_strip_rmt.h create mode 100644 hw/bsp/espressif/components/led_strip/include/led_strip_spi.h create mode 100644 hw/bsp/espressif/components/led_strip/include/led_strip_types.h create mode 100644 hw/bsp/espressif/components/led_strip/interface/led_strip_interface.h create mode 100644 hw/bsp/espressif/components/led_strip/src/led_strip_api.c create mode 100644 hw/bsp/espressif/components/led_strip/src/led_strip_rmt_dev.c create mode 100644 hw/bsp/espressif/components/led_strip/src/led_strip_rmt_dev_idf4.c create mode 100644 hw/bsp/espressif/components/led_strip/src/led_strip_rmt_encoder.c create mode 100644 hw/bsp/espressif/components/led_strip/src/led_strip_rmt_encoder.h delete mode 100644 hw/bsp/espressif/components/led_strip/src/led_strip_rmt_ws2812.c create mode 100644 hw/bsp/espressif/components/led_strip/src/led_strip_spi_dev.c delete mode 100644 hw/bsp/mcx/boards/bunny-brain/board.cmake delete mode 100644 hw/bsp/mcx/boards/bunny-brain/board.h delete mode 100644 hw/bsp/mcx/boards/bunny-brain/board.mk delete mode 100644 hw/bsp/mcx/boards/bunny-brain/clock_config.c delete mode 100644 hw/bsp/mcx/boards/bunny-brain/clock_config.h delete mode 100644 hw/bsp/mcx/boards/bunny-brain/pin_mux.c delete mode 100644 hw/bsp/mcx/boards/bunny-brain/pin_mux.h delete mode 100644 hw/bsp/mcx/boards/frdm-mcxn947/board.cmake delete mode 100644 hw/bsp/mcx/boards/frdm-mcxn947/board.h delete mode 100644 hw/bsp/mcx/boards/frdm-mcxn947/board.mk delete mode 100644 hw/bsp/mcx/boards/frdm-mcxn947/clock_config.c delete mode 100644 hw/bsp/mcx/boards/frdm-mcxn947/clock_config.h delete mode 100644 hw/bsp/mcx/boards/frdm-mcxn947/pin_mux.c delete mode 100644 hw/bsp/mcx/boards/frdm-mcxn947/pin_mux.h create mode 100644 src/class/cdc/serial/ch34x.h diff --git a/.github/workflows/build_aarch64.yml b/.github/workflows/build_aarch64.yml index 40fc8d63a..e5dbf9494 100644 --- a/.github/workflows/build_aarch64.yml +++ b/.github/workflows/build_aarch64.yml @@ -36,7 +36,7 @@ jobs: - 'broadcom_64bit' steps: - name: Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.x' diff --git a/.github/workflows/build_arm.yml b/.github/workflows/build_arm.yml index 4127db5bf..9f3270c91 100644 --- a/.github/workflows/build_arm.yml +++ b/.github/workflows/build_arm.yml @@ -46,7 +46,7 @@ jobs: - 'tm4c123 xmc4000' steps: - name: Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.x' diff --git a/.github/workflows/build_esp.yml b/.github/workflows/build_esp.yml index 33caa0edb..8fbdb31ff 100644 --- a/.github/workflows/build_esp.yml +++ b/.github/workflows/build_esp.yml @@ -8,6 +8,7 @@ on: - 'examples/**' - 'lib/**' - 'hw/**' + - 'test/hil/**' - '.github/workflows/build_esp.yml' pull_request: branches: [ master ] @@ -16,6 +17,7 @@ on: - 'examples/**' - 'lib/**' - 'hw/**' + - 'test/hil/**' - '.github/workflows/build_esp.yml' concurrency: @@ -35,7 +37,7 @@ jobs: - 'espressif_s3_devkitc' steps: - name: Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.x' @@ -46,7 +48,7 @@ jobs: uses: actions/checkout@v4 - name: Build - run: docker run --rm -v $PWD:/project -w /project espressif/idf:latest python3 tools/build_esp32.py ${{ matrix.board }} + run: docker run --rm -v $PWD:/project -w /project espressif/idf:v5.1.1 python3 tools/build_esp32.py ${{ matrix.board }} - name: Upload Artifacts for Hardware Testing if: matrix.board == 'espressif_s3_devkitc' && github.repository_owner == 'hathach' diff --git a/.github/workflows/build_iar.yml b/.github/workflows/build_iar.yml index 9f2cc0351..a0a022ecc 100644 --- a/.github/workflows/build_iar.yml +++ b/.github/workflows/build_iar.yml @@ -9,6 +9,7 @@ on: - 'lib/**' - 'hw/**' - 'tools/get_deps.py' + - 'test/hil/**' - '.github/workflows/build_iar.yml' pull_request: branches: [ master ] @@ -18,6 +19,7 @@ on: - 'lib/**' - 'hw/**' - 'tools/get_deps.py' + - 'test/hil/**' - '.github/workflows/build_iar.yml' concurrency: diff --git a/.github/workflows/build_msp430.yml b/.github/workflows/build_msp430.yml index 296dbb766..f913df913 100644 --- a/.github/workflows/build_msp430.yml +++ b/.github/workflows/build_msp430.yml @@ -36,7 +36,7 @@ jobs: steps: - name: Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.x' diff --git a/.github/workflows/build_renesas.yml b/.github/workflows/build_renesas.yml index 017a29eee..ec06c9426 100644 --- a/.github/workflows/build_renesas.yml +++ b/.github/workflows/build_renesas.yml @@ -35,7 +35,7 @@ jobs: - 'rx' steps: - name: Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.x' diff --git a/.github/workflows/build_riscv.yml b/.github/workflows/build_riscv.yml index e030bb77f..e891a3a51 100644 --- a/.github/workflows/build_riscv.yml +++ b/.github/workflows/build_riscv.yml @@ -37,7 +37,7 @@ jobs: - 'gd32vf103' steps: - name: Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.x' diff --git a/.github/workflows/build_win_mac.yml b/.github/workflows/build_win_mac.yml index 7fa1a6943..b33b5b593 100644 --- a/.github/workflows/build_win_mac.yml +++ b/.github/workflows/build_win_mac.yml @@ -35,7 +35,7 @@ jobs: steps: - name: Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.x' diff --git a/.github/workflows/cmake_arm.yml b/.github/workflows/cmake_arm.yml index 8b87fef21..f97645ad1 100644 --- a/.github/workflows/cmake_arm.yml +++ b/.github/workflows/cmake_arm.yml @@ -8,6 +8,7 @@ on: - 'examples/**' - 'lib/**' - 'hw/**' + - 'test/hil/**' - 'tools/get_deps.py' - '.github/workflows/cmake_arm.yml' pull_request: @@ -17,6 +18,7 @@ on: - 'examples/**' - 'lib/**' - 'hw/**' + - 'test/hil/**' - 'tools/get_deps.py' - '.github/workflows/cmake_arm.yml' @@ -57,7 +59,7 @@ jobs: - 'stm32u5' steps: - name: Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.x' diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 2e9ae9264..e36259daa 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.x' diff --git a/examples/device/video_capture/src/CMakeLists.txt b/examples/device/video_capture/src/CMakeLists.txt new file mode 100644 index 000000000..cef2b46ee --- /dev/null +++ b/examples/device/video_capture/src/CMakeLists.txt @@ -0,0 +1,4 @@ +# This file is for ESP-IDF only +idf_component_register(SRCS "main.c" "usb_descriptors.c" + INCLUDE_DIRS "." + REQUIRES boards tinyusb_src) diff --git a/examples/device/video_capture/src/images.h b/examples/device/video_capture/src/images.h index 784e7754c..ac372cb16 100644 --- a/examples/device/video_capture/src/images.h +++ b/examples/device/video_capture/src/images.h @@ -1,4 +1,5 @@ #if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) +// uncopmressed frame static const unsigned char frame_buffer[128 * (96 + 1) * 2] = { /* 0 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, @@ -1650,8 +1651,10 @@ static const unsigned char frame_buffer[128 * (96 + 1) * 2] = { 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, }; + #else +// mpeg compressed data (not CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) #define color_bar_0_jpg_len 511 #define color_bar_1_jpg_len 512 #define color_bar_2_jpg_len 511 diff --git a/examples/device/video_capture/src/main.c b/examples/device/video_capture/src/main.c index 711d4710a..2a2b0961f 100644 --- a/examples/device/video_capture/src/main.c +++ b/examples/device/video_capture/src/main.c @@ -40,7 +40,7 @@ * - 1000 ms : device mounted * - 2500 ms : device is suspended */ -enum { +enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, @@ -48,14 +48,25 @@ enum { static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; -void led_blinking_task(void); -void video_task(void); +void led_blinking_task(void* param); +void usb_device_task(void *param); +void video_task(void* param); -/*------------- MAIN -------------*/ -int main(void) -{ +#if CFG_TUSB_OS == OPT_OS_FREERTOS +void freertos_init_task(void); +#endif + + +//--------------------------------------------------------------------+ +// Main +//--------------------------------------------------------------------+ +int main(void) { board_init(); + // If using FreeRTOS: create blinky, tinyusb device, video task +#if CFG_TUSB_OS == OPT_OS_FREERTOS + freertos_init_task(); +#else // init device stack on configured roothub port tud_init(BOARD_TUD_RHPORT); @@ -63,13 +74,12 @@ int main(void) board_init_after_tusb(); } - while (1) - { + while (1) { tud_task(); // tinyusb device task - led_blinking_task(); - - video_task(); + led_blinking_task(NULL); + video_task(NULL); } +#endif } //--------------------------------------------------------------------+ @@ -77,33 +87,28 @@ 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; } - //--------------------------------------------------------------------+ // USB Video //--------------------------------------------------------------------+ @@ -111,11 +116,12 @@ static unsigned frame_num = 0; static unsigned tx_busy = 0; static unsigned interval_ms = 1000 / FRAME_RATE; -/* YUY2 frame buffer */ #ifdef CFG_EXAMPLE_VIDEO_READONLY +// For mcus that does not have enough SRAM for frame buffer, we use fixed frame data. +// To further reduce the size, we use MJPEG format instead of YUY2. #include "images.h" -# if !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) +#if !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) static struct { uint32_t size; uint8_t const *buffer; @@ -129,29 +135,30 @@ static struct { {color_bar_6_jpg_len, color_bar_6_jpg}, {color_bar_7_jpg_len, color_bar_7_jpg}, }; -# endif +#endif #else + +// YUY2 frame buffer static uint8_t frame_buffer[FRAME_WIDTH * FRAME_HEIGHT * 16 / 8]; -static void fill_color_bar(uint8_t *buffer, unsigned start_position) -{ - /* EBU color bars - * See also https://stackoverflow.com/questions/6939422 */ + +static void fill_color_bar(uint8_t* buffer, unsigned start_position) { + /* EBU color bars: https://stackoverflow.com/questions/6939422 */ static uint8_t const bar_color[8][4] = { - /* Y, U, Y, V */ - { 235, 128, 235, 128}, /* 100% White */ - { 219, 16, 219, 138}, /* Yellow */ - { 188, 154, 188, 16}, /* Cyan */ - { 173, 42, 173, 26}, /* Green */ - { 78, 214, 78, 230}, /* Magenta */ - { 63, 102, 63, 240}, /* Red */ - { 32, 240, 32, 118}, /* Blue */ - { 16, 128, 16, 128}, /* Black */ + /* Y, U, Y, V */ + { 235, 128, 235, 128}, /* 100% White */ + { 219, 16, 219, 138}, /* Yellow */ + { 188, 154, 188, 16}, /* Cyan */ + { 173, 42, 173, 26}, /* Green */ + { 78, 214, 78, 230}, /* Magenta */ + { 63, 102, 63, 240}, /* Red */ + { 32, 240, 32, 118}, /* Blue */ + { 16, 128, 16, 128}, /* Black */ }; - uint8_t *p; + uint8_t* p; /* Generate the 1st line */ - uint8_t *end = &buffer[FRAME_WIDTH * 2]; + uint8_t* end = &buffer[FRAME_WIDTH * 2]; unsigned idx = (FRAME_WIDTH / 2 - 1) - (start_position % (FRAME_WIDTH / 2)); p = &buffer[idx * 4]; for (unsigned i = 0; i < 8; ++i) { @@ -163,6 +170,7 @@ static void fill_color_bar(uint8_t *buffer, unsigned start_position) } } } + /* Duplicate the 1st line to the others */ p = &buffer[FRAME_WIDTH * 2]; for (unsigned i = 1; i < FRAME_HEIGHT; ++i) { @@ -170,32 +178,33 @@ static void fill_color_bar(uint8_t *buffer, unsigned start_position) p += FRAME_WIDTH * 2; } } + #endif -void video_task(void) -{ +void video_send_frame(void) { static unsigned start_ms = 0; static unsigned already_sent = 0; if (!tud_video_n_streaming(0, 0)) { - already_sent = 0; - frame_num = 0; + already_sent = 0; + frame_num = 0; return; } if (!already_sent) { already_sent = 1; + tx_busy = 1; start_ms = board_millis(); #ifdef CFG_EXAMPLE_VIDEO_READONLY -# if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) + #if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)&frame_buffer[(frame_num % (FRAME_WIDTH / 2)) * 4], FRAME_WIDTH * FRAME_HEIGHT * 16/8); -# else + #else tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)frames[frame_num % 8].buffer, frames[frame_num % 8].size); -# endif + #endif #else fill_color_bar(frame_buffer, frame_num); - tud_video_n_frame_xfer(0, 0, (void*)frame_buffer, FRAME_WIDTH * FRAME_HEIGHT * 16/8); + tud_video_n_frame_xfer(0, 0, (void*) frame_buffer, FRAME_WIDTH * FRAME_HEIGHT * 16 / 8); #endif } @@ -203,49 +212,140 @@ void video_task(void) if (cur - start_ms < interval_ms) return; // not enough time if (tx_busy) return; start_ms += interval_ms; + tx_busy = 1; #ifdef CFG_EXAMPLE_VIDEO_READONLY -# if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) + #if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)&frame_buffer[(frame_num % (FRAME_WIDTH / 2)) * 4], FRAME_WIDTH * FRAME_HEIGHT * 16/8); -# else + #else tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)frames[frame_num % 8].buffer, frames[frame_num % 8].size); -# endif + #endif #else fill_color_bar(frame_buffer, frame_num); - tud_video_n_frame_xfer(0, 0, (void*)frame_buffer, FRAME_WIDTH * FRAME_HEIGHT * 16/8); + tud_video_n_frame_xfer(0, 0, (void*) frame_buffer, FRAME_WIDTH * FRAME_HEIGHT * 16 / 8); #endif } -void tud_video_frame_xfer_complete_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) -{ - (void)ctl_idx; (void)stm_idx; + +void video_task(void* param) { + (void) param; + + while(1) { + video_send_frame(); + + #if CFG_TUSB_OS == OPT_OS_FREERTOS + vTaskDelay(interval_ms / portTICK_PERIOD_MS); + #else + return; + #endif + } +} + +void tud_video_frame_xfer_complete_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) { + (void) ctl_idx; + (void) stm_idx; tx_busy = 0; /* flip buffer */ ++frame_num; } int tud_video_commit_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, - video_probe_and_commit_control_t const *parameters) -{ - (void)ctl_idx; (void)stm_idx; + video_probe_and_commit_control_t const* parameters) { + (void) ctl_idx; + (void) stm_idx; /* convert unit to ms from 100 ns */ interval_ms = parameters->dwFrameInterval / 10000; return VIDEO_ERROR_NONE; } //--------------------------------------------------------------------+ -// BLINKING TASK +// Blinking Task //--------------------------------------------------------------------+ -void led_blinking_task(void) -{ +void led_blinking_task(void* param) { + (void) param; 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; + while (1) { + #if CFG_TUSB_OS == OPT_OS_FREERTOS + vTaskDelay(blink_interval_ms / portTICK_PERIOD_MS); + #else + if (board_millis() - start_ms < blink_interval_ms) return; // not enough time + #endif - board_led_write(led_state); - led_state = 1 - led_state; // toggle + start_ms += blink_interval_ms; + board_led_write(led_state); + led_state = 1 - led_state; // toggle + } } + +//--------------------------------------------------------------------+ +// FreeRTOS +//--------------------------------------------------------------------+ +#if CFG_TUSB_OS == OPT_OS_FREERTOS + +#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) + #define USBD_STACK_SIZE 4096 + int main(void); + void app_main(void) { + main(); + } +#else + // Increase stack size when debug log is enabled + #define USBD_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1) +#endif + +// 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 video_stack[VIDEO_STACK_SIZE]; +StaticTask_t video_taskdef; +#endif + +// USB Device Driver task +// This top level thread process all usb events and invoke callbacks +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. + tud_init(BOARD_TUD_RHPORT); + + if (board_init_after_tusb) { + board_init_after_tusb(); + } + + // RTOS forever loop + while (1) { + // put this thread to waiting state until there is new events + tud_task(); + } +} + +void freertos_init_task(void) { + #if configSUPPORT_STATIC_ALLOCATION + xTaskCreateStatic(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, blinky_stack, &blinky_taskdef); + xTaskCreateStatic(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_device_stack, &usb_device_taskdef); + xTaskCreateStatic(video_task, "cdc", VIDEO_STACK_SIZE, NULL, configMAX_PRIORITIES - 2, video_stack, &video_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(video_task, "video", VIDEO_STACK_SZIE, NULL, configMAX_PRIORITIES - 2, NULL); + #endif + + // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3 + #if !TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) + vTaskStartScheduler(); + #endif +} +#endif diff --git a/examples/device/video_capture/src/tusb_config.h b/examples/device/video_capture/src/tusb_config.h index 274bf2b9c..bdfc37d87 100644 --- a/examples/device/video_capture/src/tusb_config.h +++ b/examples/device/video_capture/src/tusb_config.h @@ -57,6 +57,11 @@ #define CFG_TUSB_OS OPT_OS_NONE #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 @@ -97,11 +102,14 @@ // The number of video streaming interfaces #define CFG_TUD_VIDEO_STREAMING 1 -// video streaming endpoint size +// video streaming endpoint buffer size #define CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE 256 // use bulk endpoint for streaming interface -#define CFG_TUD_VIDEO_STREAMING_BULK 0 +#define CFG_TUD_VIDEO_STREAMING_BULK 1 + +//#define CFG_EXAMPLE_VIDEO_READONLY +//#define CFG_EXAMPLE_VIDEO_DISABLE_MJPEG #ifdef __cplusplus } diff --git a/examples/device/video_capture/src/usb_descriptors.c b/examples/device/video_capture/src/usb_descriptors.c index 49919fc58..f308c75a7 100644 --- a/examples/device/video_capture/src/usb_descriptors.c +++ b/examples/device/video_capture/src/usb_descriptors.c @@ -40,11 +40,30 @@ #define USB_VID 0xCafe #define USB_BCD 0x0200 +// String Descriptor Index +enum { + STRID_LANGID = 0, + STRID_MANUFACTURER, + STRID_PRODUCT, + STRID_SERIAL, + STRID_UVC_CONTROL, + STRID_UVC_STREAMING, +}; + +// 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 UVC Control", // 4: UVC Interface + "TinyUSB UVC Streaming", // 5: UVC Interface +}; + //--------------------------------------------------------------------+ // 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, @@ -61,201 +80,374 @@ tusb_desc_device_t const desc_device = .idProduct = USB_PID, .bcdDevice = 0x0100, - .iManufacturer = 0x01, - .iProduct = 0x02, - .iSerialNumber = 0x03, + .iManufacturer = STRID_MANUFACTURER, + .iProduct = STRID_PRODUCT, + .iSerialNumber = STRID_SERIAL, .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 //--------------------------------------------------------------------+ -#if defined(CFG_EXAMPLE_VIDEO_READONLY) && !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) -# if 1 == CFG_TUD_VIDEO_STREAMING_BULK -# define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_VIDEO_CAPTURE_DESC_MJPEG_BULK_LEN) -# else -# define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_VIDEO_CAPTURE_DESC_MJPEG_LEN) -# endif -#else -# if 1 == CFG_TUD_VIDEO_STREAMING_BULK -# define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_VIDEO_CAPTURE_DESC_UNCOMPR_BULK_LEN) -# else -# define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_VIDEO_CAPTURE_DESC_UNCOMPR_LEN) -# endif -#endif +/* Time stamp base clock. It is a deprecated parameter. */ +#define UVC_CLOCK_FREQUENCY 27000000 +/* video capture path */ +#define UVC_ENTITY_CAP_INPUT_TERMINAL 0x01 +#define UVC_ENTITY_CAP_OUTPUT_TERMINAL 0x02 + +enum { + ITF_NUM_VIDEO_CONTROL, + ITF_NUM_VIDEO_STREAMING, + ITF_NUM_TOTAL +}; + +// Select appropriate endpoint number #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, 5 Bulk etc ... -#if 1 == CFG_TUD_VIDEO_STREAMING_BULK - #define EPNUM_VIDEO_IN 0x82 -#else - #define EPNUM_VIDEO_IN 0x83 -#endif - + #define EPNUM_VIDEO_IN (CFG_TUD_VIDEO_STREAMING_BULK ? 0x82 : 0x83) #elif TU_CHECK_MCU(OPT_MCU_NRF5X) // nRF5x ISO can only be endpoint 8 - #define EPNUM_VIDEO_IN 0x88 - + #define EPNUM_VIDEO_IN (CFG_TUD_VIDEO_STREAMING_BULK ? 0x81 : 0x88) #else #define EPNUM_VIDEO_IN 0x81 - #endif -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, 0, 500), - - // IAD for Video Control #if defined(CFG_EXAMPLE_VIDEO_READONLY) && !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) -# if 1 == CFG_TUD_VIDEO_STREAMING_BULK - TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG_BULK(4, EPNUM_VIDEO_IN, - FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, - 64) -# else - TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG(4, EPNUM_VIDEO_IN, - FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, - CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE) -# endif + #define USE_MJPEG 1 #else -# if 1 == CFG_TUD_VIDEO_STREAMING_BULK - TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR_BULK(4, EPNUM_VIDEO_IN, - FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, - 64) -# else - TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR(4, EPNUM_VIDEO_IN, - FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, - CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE) -# endif + #define USE_MJPEG 0 #endif + +#define USE_ISO_STREAMING (!CFG_TUD_VIDEO_STREAMING_BULK) + +typedef struct TU_ATTR_PACKED { + tusb_desc_interface_t itf; + tusb_desc_video_control_header_1itf_t header; + tusb_desc_video_control_camera_terminal_t camera_terminal; + tusb_desc_video_control_output_terminal_t output_terminal; +} uvc_control_desc_t; + +/* Windows support YUY2 and NV12 + * https://docs.microsoft.com/en-us/windows-hardware/drivers/stream/usb-video-class-driver-overview */ + +typedef struct TU_ATTR_PACKED { + tusb_desc_interface_t itf; + tusb_desc_video_streaming_input_header_1byte_t header; + +#if USE_MJPEG + tusb_desc_video_format_mjpeg_t format; + tusb_desc_video_frame_mjpeg_continuous_t frame; +#else + tusb_desc_video_format_uncompressed_t format; + tusb_desc_video_frame_uncompressed_continuous_t frame; +#endif + + tusb_desc_video_streaming_color_matching_t color; + +#if USE_ISO_STREAMING + // For ISO streaming, USB spec requires to alternate interface + tusb_desc_interface_t itf_alt; +#endif + + tusb_desc_endpoint_t ep; +} uvc_streaming_desc_t; + +typedef struct TU_ATTR_PACKED { + tusb_desc_configuration_t config; + tusb_desc_interface_assoc_t iad; + uvc_control_desc_t video_control; + uvc_streaming_desc_t video_streaming; +} uvc_cfg_desc_t; + +const uvc_cfg_desc_t desc_fs_configuration = { + .config = { + .bLength = sizeof(tusb_desc_configuration_t), + .bDescriptorType = TUSB_DESC_CONFIGURATION, + + .wTotalLength = sizeof(uvc_cfg_desc_t), + .bNumInterfaces = ITF_NUM_TOTAL, + .bConfigurationValue = 1, + .iConfiguration = 0, + .bmAttributes = TU_BIT(7), + .bMaxPower = 100 / 2 + }, + .iad = { + .bLength = sizeof(tusb_desc_interface_assoc_t), + .bDescriptorType = TUSB_DESC_INTERFACE_ASSOCIATION, + + .bFirstInterface = ITF_NUM_VIDEO_CONTROL, + .bInterfaceCount = 2, + .bFunctionClass = TUSB_CLASS_VIDEO, + .bFunctionSubClass = VIDEO_SUBCLASS_INTERFACE_COLLECTION, + .bFunctionProtocol = VIDEO_ITF_PROTOCOL_UNDEFINED, + .iFunction = 0 + }, + + .video_control = { + .itf = { + .bLength = sizeof(tusb_desc_interface_t), + .bDescriptorType = TUSB_DESC_INTERFACE, + + .bInterfaceNumber = ITF_NUM_VIDEO_CONTROL, + .bAlternateSetting = 0, + .bNumEndpoints = 0, + .bInterfaceClass = TUSB_CLASS_VIDEO, + .bInterfaceSubClass = VIDEO_SUBCLASS_CONTROL, + .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, + .iInterface = STRID_UVC_CONTROL + }, + .header = { + .bLength = sizeof(tusb_desc_video_control_header_1itf_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VC_HEADER, + + .bcdUVC = VIDEO_BCD_1_50, + .wTotalLength = sizeof(uvc_control_desc_t) - sizeof(tusb_desc_interface_t), // CS VC descriptors only + .dwClockFrequency = UVC_CLOCK_FREQUENCY, + .bInCollection = 1, + .baInterfaceNr = { ITF_NUM_VIDEO_STREAMING } + }, + .camera_terminal = { + .bLength = sizeof(tusb_desc_video_control_camera_terminal_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VC_INPUT_TERMINAL, + + .bTerminalID = UVC_ENTITY_CAP_INPUT_TERMINAL, + .wTerminalType = VIDEO_ITT_CAMERA, + .bAssocTerminal = 0, + .iTerminal = 0, + .wObjectiveFocalLengthMin = 0, + .wObjectiveFocalLengthMax = 0, + .wOcularFocalLength = 0, + .bControlSize = 3, + .bmControls = { 0, 0, 0 } + }, + .output_terminal = { + .bLength = sizeof(tusb_desc_video_control_output_terminal_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VC_OUTPUT_TERMINAL, + + .bTerminalID = UVC_ENTITY_CAP_OUTPUT_TERMINAL, + .wTerminalType = VIDEO_TT_STREAMING, + .bAssocTerminal = 0, + .bSourceID = UVC_ENTITY_CAP_INPUT_TERMINAL, + .iTerminal = 0 + } + }, + + .video_streaming = { + .itf = { + .bLength = sizeof(tusb_desc_interface_t), + .bDescriptorType = TUSB_DESC_INTERFACE, + + .bInterfaceNumber = ITF_NUM_VIDEO_STREAMING, + .bAlternateSetting = 0, + .bNumEndpoints = CFG_TUD_VIDEO_STREAMING_BULK, // bulk 1, iso 0 + .bInterfaceClass = TUSB_CLASS_VIDEO, + .bInterfaceSubClass = VIDEO_SUBCLASS_STREAMING, + .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, + .iInterface = STRID_UVC_STREAMING + }, + .header = { + .bLength = sizeof(tusb_desc_video_streaming_input_header_1byte_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_INPUT_HEADER, + + .bNumFormats = 1, + .wTotalLength = sizeof(uvc_streaming_desc_t) - sizeof(tusb_desc_interface_t) + - sizeof(tusb_desc_endpoint_t) - (USE_ISO_STREAMING ? sizeof(tusb_desc_interface_t) : 0) , // CS VS descriptors only + .bEndpointAddress = EPNUM_VIDEO_IN, + .bmInfo = 0, + .bTerminalLink = UVC_ENTITY_CAP_OUTPUT_TERMINAL, + .bStillCaptureMethod = 0, + .bTriggerSupport = 0, + .bTriggerUsage = 0, + .bControlSize = 1, + .bmaControls = { 0 } + }, + .format = { +#if USE_MJPEG + .bLength = sizeof(tusb_desc_video_format_mjpeg_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_FORMAT_MJPEG, + .bFormatIndex = 1, // 1-based index + .bNumFrameDescriptors = 1, + .bmFlags = 0, +#else + .bLength = sizeof(tusb_desc_video_format_uncompressed_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED, + .bFormatIndex = 1, // 1-based index + .bNumFrameDescriptors = 1, + .guidFormat = { TUD_VIDEO_GUID_YUY2 }, + .bBitsPerPixel = 16, +#endif + .bDefaultFrameIndex = 1, + .bAspectRatioX = 0, + .bAspectRatioY = 0, + .bmInterlaceFlags = 0, + .bCopyProtect = 0 + }, + .frame = { +#if USE_MJPEG + .bLength = sizeof(tusb_desc_video_frame_mjpeg_continuous_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_FRAME_MJPEG, +#else + .bLength = sizeof(tusb_desc_video_frame_uncompressed_continuous_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED, +#endif + .bFrameIndex = 1, // 1-based index + .bmCapabilities = 0, + .wWidth = FRAME_WIDTH, + .wHeight = FRAME_HEIGHT, + .dwMinBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * 1, + .dwMaxBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * FRAME_RATE, + .dwMaxVideoFrameBufferSize = FRAME_WIDTH * FRAME_HEIGHT * 16 / 8, + .dwDefaultFrameInterval = 10000000 / FRAME_RATE, + .bFrameIntervalType = 0, // continuous + .dwFrameInterval = { + 10000000 / FRAME_RATE, // min + 10000000, // max + 10000000 / FRAME_RATE // step + } + }, + .color = { + .bLength = sizeof(tusb_desc_video_streaming_color_matching_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_COLORFORMAT, + + .bColorPrimaries = VIDEO_COLOR_PRIMARIES_BT709, + .bTransferCharacteristics = VIDEO_COLOR_XFER_CH_BT709, + .bMatrixCoefficients = VIDEO_COLOR_COEF_SMPTE170M + }, + +#if USE_ISO_STREAMING + .itf_alt = { + .bLength = sizeof(tusb_desc_interface_t), + .bDescriptorType = TUSB_DESC_INTERFACE, + + .bInterfaceNumber = ITF_NUM_VIDEO_STREAMING, + .bAlternateSetting = 1, + .bNumEndpoints = 1, + .bInterfaceClass = TUSB_CLASS_VIDEO, + .bInterfaceSubClass = VIDEO_SUBCLASS_STREAMING, + .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, + .iInterface = STRID_UVC_STREAMING + }, +#endif + + .ep = { + .bLength = sizeof(tusb_desc_endpoint_t), + .bDescriptorType = TUSB_DESC_ENDPOINT, + + .bEndpointAddress = EPNUM_VIDEO_IN, + .bmAttributes = { + .xfer = CFG_TUD_VIDEO_STREAMING_BULK ? TUSB_XFER_BULK : TUSB_XFER_ISOCHRONOUS, + .sync = CFG_TUD_VIDEO_STREAMING_BULK ? 0 : 1 // asynchronous + }, + .wMaxPacketSize = CFG_TUD_VIDEO_STREAMING_BULK ? 64 : CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE, + .bInterval = 1 + } + } }; #if TUD_OPT_HIGH_SPEED -// Per USB specs: high speed capable device must report device_qualifier and other_speed_configuration +uvc_cfg_desc_t 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, 0, 500), +static uint8_t * get_hs_configuration_desc(void) { + static bool init = false; - // IAD for Video Control -#if defined(CFG_EXAMPLE_VIDEO_READONLY) && !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) -# if 1 == CFG_TUD_VIDEO_STREAMING_BULK - TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG_BULK(4, EPNUM_VIDEO_IN, - FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, - 512) -# else - TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG(4, EPNUM_VIDEO_IN, - FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, - CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE) -# endif -#else -# if 1 == CFG_TUD_VIDEO_STREAMING_BULK - TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR_BULK(4, EPNUM_VIDEO_IN, - FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, - 512) -# else - TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR(4, EPNUM_VIDEO_IN, - FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, - CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE) -# endif -#endif -}; + if (!init) { + desc_hs_configuration = desc_fs_configuration; + // change endpoint bulk size to 512 if bulk streaming + if (CFG_TUD_VIDEO_STREAMING_BULK) { + desc_hs_configuration.video_streaming.ep.wMaxPacketSize = 512; + } + } + init = true; + + return (uint8_t *) &desc_hs_configuration; +} // 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_t), - .bDescriptorType = TUSB_DESC_DEVICE, - .bcdUSB = USB_BCD, +tusb_desc_device_qualifier_t const desc_device_qualifier = { + .bLength = sizeof(tusb_desc_device_t), + .bDescriptorType = TUSB_DESC_DEVICE, + .bcdUSB = USB_BCD, - .bDeviceClass = TUSB_CLASS_MISC, - .bDeviceSubClass = MISC_SUBCLASS_COMMON, - .bDeviceProtocol = MISC_PROTOCOL_IAD, + .bDeviceClass = TUSB_CLASS_MISC, + .bDeviceSubClass = MISC_SUBCLASS_COMMON, + .bDeviceProtocol = MISC_PROTOCOL_IAD, - .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, - .bNumConfigurations = 0x01, - .bReserved = 0x00 + .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) -{ +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 - return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_fs_configuration : desc_hs_configuration; + if (tud_speed_get() == TUSB_SPEED_HIGH) { + return (uint8_t const*) &desc_fs_configuration; + } else { + return get_hs_configuration_desc(); + } } - #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) -{ +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; + if (tud_speed_get() == TUSB_SPEED_HIGH) { + return get_hs_configuration_desc(); + } else #endif + { + return (uint8_t const*) &desc_fs_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 Device", // 2: Product - NULL, // 3: Serials will use unique ID if possible - "TinyUSB UVC", // 4: UVC 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; @@ -269,17 +461,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/device/video_capture/src/usb_descriptors.h b/examples/device/video_capture/src/usb_descriptors.h index b924c8dbe..12d41b2f3 100644 --- a/examples/device/video_capture/src/usb_descriptors.h +++ b/examples/device/video_capture/src/usb_descriptors.h @@ -27,21 +27,11 @@ #ifndef _USB_DESCRIPTORS_H_ #define _USB_DESCRIPTORS_H_ -/* Time stamp base clock. It is a deprecated parameter. */ -#define UVC_CLOCK_FREQUENCY 27000000 -/* video capture path */ -#define UVC_ENTITY_CAP_INPUT_TERMINAL 0x01 -#define UVC_ENTITY_CAP_OUTPUT_TERMINAL 0x02 - #define FRAME_WIDTH 128 #define FRAME_HEIGHT 96 #define FRAME_RATE 10 -enum { - ITF_NUM_VIDEO_CONTROL, - ITF_NUM_VIDEO_STREAMING, - ITF_NUM_TOTAL -}; +// NOTE: descriptor template is not used but leave here as reference #define TUD_VIDEO_CAPTURE_DESC_UNCOMPR_LEN (\ TUD_VIDEO_DESC_IAD_LEN\ @@ -126,23 +116,17 @@ enum { #define TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR(_stridx, _epin, _width, _height, _fps, _epsize) \ TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \ /* Video control 0 */ \ - TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ - TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \ - /* wTotalLength - bLength */ \ - TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \ - UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ - TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\ - /*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\ - /*wObjectiveFocalLength*/0, /*bmControls*/0), \ + TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ + /* Header: UVC 1.5, length of followed descs, clock (deprecated), streaming interfaces */ \ + TUD_VIDEO_DESC_CS_VC(0x0150, TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ + /* Camera Terminal: ID, bAssocTerminal, iTerminal, focal min, max, length, bmControl */ \ + TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0, 0, 0, 0, 0), \ TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \ /* Video stream alt. 0 */ \ TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 0, _stridx), \ /* Video stream header for without still image capture */ \ TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ - /*wTotalLength - bLength */\ - TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN\ - + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN\ - + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ + /*wTotalLength - bLength */ TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ /*bmaControls(1)*/0), \ @@ -152,7 +136,7 @@ enum { /* Video stream frame format */ \ TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT(/*bFrameIndex */1, 0, _width, _height, \ _width * _height * 16, _width * _height * 16 * _fps, \ - _width * _height * 16, \ + _width * _height * 16 / 8, \ (10000000/_fps), (10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \ /* VS alt 1 */\ @@ -163,23 +147,17 @@ enum { #define TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG(_stridx, _epin, _width, _height, _fps, _epsize) \ TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \ /* Video control 0 */ \ - TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ - TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \ - /* wTotalLength - bLength */ \ - TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \ - UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ - TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\ - /*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\ - /*wObjectiveFocalLength*/0, /*bmControls*/0), \ + TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ + /* Header: UVC 1.5, length of followed descs, clock (deprecated), streaming interfaces */ \ + TUD_VIDEO_DESC_CS_VC(0x0150, TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ + /* Camera Terminal: ID, bAssocTerminal, iTerminal, focal min, max, length, bmControl */ \ + TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0, 0, 0, 0, 0), \ TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \ /* Video stream alt. 0 */ \ TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 0, _stridx), \ /* Video stream header for without still image capture */ \ TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ - /*wTotalLength - bLength */\ - TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN\ - + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN\ - + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ + /*wTotalLength - bLength */ TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ /*bmaControls(1)*/0), \ @@ -202,22 +180,17 @@ enum { TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \ /* Video control 0 */ \ TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ - TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \ - /* wTotalLength - bLength */ \ - TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \ - UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ - TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\ - /*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\ - /*wObjectiveFocalLength*/0, /*bmControls*/0), \ + /* Header: UVC 1.5, length of followed descs, clock (deprecated), streaming interfaces */ \ + TUD_VIDEO_DESC_CS_VC(0x0150, TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ + /* Camera Terminal: ID, bAssocTerminal, iTerminal, focal min, max, length, bmControl */ \ + TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0, 0, 0, 0, 0), \ TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \ /* Video stream alt. 0 */ \ TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 1, _stridx), \ /* Video stream header for without still image capture */ \ TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ /*wTotalLength - bLength */\ - TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN\ - + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN\ - + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ + TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ /*bmaControls(1)*/0), \ @@ -227,7 +200,7 @@ enum { /* Video stream frame format */ \ TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT(/*bFrameIndex */1, 0, _width, _height, \ _width * _height * 16, _width * _height * 16 * _fps, \ - _width * _height * 16, \ + _width * _height * 16 / 8, \ (10000000/_fps), (10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \ TUD_VIDEO_DESC_EP_BULK(_epin, _epsize, 1) @@ -235,23 +208,17 @@ enum { #define TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG_BULK(_stridx, _epin, _width, _height, _fps, _epsize) \ TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \ /* Video control 0 */ \ - TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ - TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \ - /* wTotalLength - bLength */ \ - TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \ - UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ - TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\ - /*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\ - /*wObjectiveFocalLength*/0, /*bmControls*/0), \ - TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \ + TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ + /* Header: UVC 1.5, length of followed descs, clock (deprecated), streaming interfaces */ \ + TUD_VIDEO_DESC_CS_VC(0x0150, TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ + /* Camera Terminal: ID, bAssocTerminal, iTerminal, focal min, max, length, bmControl */ \ + TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0, 0, 0, 0, 0), \ + TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, UVC_ENTITY_CAP_INPUT_TERMINAL, 0), \ /* Video stream alt. 0 */ \ TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 1, _stridx), \ /* Video stream header for without still image capture */ \ TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ - /*wTotalLength - bLength */\ - TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN\ - + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN\ - + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ + /*wTotalLength - bLength */ TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ /*bmaControls(1)*/0), \ diff --git a/examples/host/cdc_msc_hid/src/cdc_app.c b/examples/host/cdc_msc_hid/src/cdc_app.c index a1b26e49c..e275e7943 100644 --- a/examples/host/cdc_msc_hid/src/cdc_app.c +++ b/examples/host/cdc_msc_hid/src/cdc_app.c @@ -27,20 +27,11 @@ #include "tusb.h" #include "bsp/board_api.h" -//--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM DECLARATION -//--------------------------------------------------------------------+ - - -//------------- IMPLEMENTATION -------------// - -size_t get_console_inputs(uint8_t* buf, size_t bufsize) -{ +size_t get_console_inputs(uint8_t* buf, size_t bufsize) { size_t count = 0; - while (count < bufsize) - { + while (count < bufsize) { int ch = board_getchar(); - if ( ch <= 0 ) break; + if (ch <= 0) break; buf[count] = (uint8_t) ch; count++; @@ -49,22 +40,18 @@ size_t get_console_inputs(uint8_t* buf, size_t bufsize) return count; } -void cdc_app_task(void) -{ - uint8_t buf[64+1]; // +1 for extra null character - uint32_t const bufsize = sizeof(buf)-1; +void cdc_app_task(void) { + uint8_t buf[64 + 1]; // +1 for extra null character + uint32_t const bufsize = sizeof(buf) - 1; uint32_t count = get_console_inputs(buf, bufsize); buf[count] = 0; // loop over all mounted interfaces - for(uint8_t idx=0; idx cdc interfaces - if (count) - { + if (count) { tuh_cdc_write(idx, buf, count); tuh_cdc_write_flush(idx); } @@ -72,11 +59,14 @@ void cdc_app_task(void) } } +//--------------------------------------------------------------------+ +// TinyUSB callbacks +//--------------------------------------------------------------------+ + // Invoked when received new data -void tuh_cdc_rx_cb(uint8_t idx) -{ - uint8_t buf[64+1]; // +1 for extra null character - uint32_t const bufsize = sizeof(buf)-1; +void tuh_cdc_rx_cb(uint8_t idx) { + uint8_t buf[64 + 1]; // +1 for extra null character + uint32_t const bufsize = sizeof(buf) - 1; // forward cdc interfaces -> console uint32_t count = tuh_cdc_read(idx, buf, bufsize); @@ -85,29 +75,35 @@ void tuh_cdc_rx_cb(uint8_t idx) printf((char*) buf); } -void tuh_cdc_mount_cb(uint8_t idx) -{ - tuh_itf_info_t itf_info = { 0 }; +// Invoked when a device with CDC interface is mounted +// idx is index of cdc interface in the internal pool. +void tuh_cdc_mount_cb(uint8_t idx) { + tuh_itf_info_t itf_info = {0}; tuh_cdc_itf_get_info(idx, &itf_info); - printf("CDC Interface is mounted: address = %u, itf_num = %u\r\n", itf_info.daddr, itf_info.desc.bInterfaceNumber); + printf("CDC Interface is mounted: address = %u, itf_num = %u\r\n", itf_info.daddr, + itf_info.desc.bInterfaceNumber); #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM - // CFG_TUH_CDC_LINE_CODING_ON_ENUM must be defined for line coding is set by tinyusb in enumeration - // otherwise you need to call tuh_cdc_set_line_coding() first - cdc_line_coding_t line_coding = { 0 }; - if ( tuh_cdc_get_local_line_coding(idx, &line_coding) ) - { + // If CFG_TUH_CDC_LINE_CODING_ON_ENUM is defined, line coding will be set by tinyusb stack + // while eneumerating new cdc device + cdc_line_coding_t line_coding = {0}; + if (tuh_cdc_get_local_line_coding(idx, &line_coding)) { printf(" Baudrate: %lu, Stop Bits : %u\r\n", line_coding.bit_rate, line_coding.stop_bits); - printf(" Parity : %u, Data Width: %u\r\n", line_coding.parity , line_coding.data_bits); + printf(" Parity : %u, Data Width: %u\r\n", line_coding.parity, line_coding.data_bits); } +#else + // Set Line Coding upon mounted + cdc_line_coding_t new_line_coding = { 115200, CDC_LINE_CODING_STOP_BITS_1, CDC_LINE_CODING_PARITY_NONE, 8 }; + tuh_cdc_set_line_coding(idx, &new_line_coding, NULL, 0); #endif } -void tuh_cdc_umount_cb(uint8_t idx) -{ - tuh_itf_info_t itf_info = { 0 }; +// Invoked when a device with CDC interface is unmounted +void tuh_cdc_umount_cb(uint8_t idx) { + tuh_itf_info_t itf_info = {0}; tuh_cdc_itf_get_info(idx, &itf_info); - printf("CDC Interface is unmounted: address = %u, itf_num = %u\r\n", itf_info.daddr, itf_info.desc.bInterfaceNumber); + printf("CDC Interface is unmounted: address = %u, itf_num = %u\r\n", itf_info.daddr, + itf_info.desc.bInterfaceNumber); } diff --git a/examples/host/cdc_msc_hid/src/tusb_config.h b/examples/host/cdc_msc_hid/src/tusb_config.h index 61abb85eb..76d59c316 100644 --- a/examples/host/cdc_msc_hid/src/tusb_config.h +++ b/examples/host/cdc_msc_hid/src/tusb_config.h @@ -105,6 +105,7 @@ #define CFG_TUH_CDC 1 // CDC ACM #define CFG_TUH_CDC_FTDI 1 // FTDI Serial. FTDI is not part of CDC class, only to re-use CDC driver API #define CFG_TUH_CDC_CP210X 1 // CP210x Serial. CP210X is not part of CDC class, only to re-use CDC driver API +#define CFG_TUH_CDC_CH34X 1 // CH340 or CH341 Serial. CH34X is not part of CDC class, only to re-use CDC driver API #define CFG_TUH_HID (3*CFG_TUH_DEVICE_MAX) // typical keyboard + mouse device can have 3-4 HID interfaces #define CFG_TUH_MSC 1 #define CFG_TUH_VENDOR 0 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 c661f47be..bb7c3388d 100644 --- a/examples/host/cdc_msc_hid_freertos/src/tusb_config.h +++ b/examples/host/cdc_msc_hid_freertos/src/tusb_config.h @@ -110,6 +110,7 @@ #define CFG_TUH_CDC 1 // CDC ACM #define CFG_TUH_CDC_FTDI 1 // FTDI Serial. FTDI is not part of CDC class, only to re-use CDC driver API #define CFG_TUH_CDC_CP210X 1 // CP210x Serial. CP210X is not part of CDC class, only to re-use CDC driver API +#define CFG_TUH_CDC_CH34X 1 // CH340 or CH341 Serial. CH34X is not part of CDC class, only to re-use CDC driver API #define CFG_TUH_HID (3*CFG_TUH_DEVICE_MAX) // typical keyboard + mouse device can have 3-4 HID interfaces #define CFG_TUH_MSC 1 #define CFG_TUH_VENDOR 0 diff --git a/hw/bsp/board_api.h b/hw/bsp/board_api.h index 404509a28..0c8a35924 100644 --- a/hw/bsp/board_api.h +++ b/hw/bsp/board_api.h @@ -33,9 +33,26 @@ extern "C" { #include #include - #include "tusb.h" +#if CFG_TUSB_OS == OPT_OS_FREERTOS +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) + // 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" +#else + #include "FreeRTOS.h" + #include "semphr.h" + #include "queue.h" + #include "task.h" + #include "timers.h" +#endif +#endif + // Define the default baudrate #ifndef CFG_BOARD_UART_BAUDRATE #define CFG_BOARD_UART_BAUDRATE 115200 ///< Default baud rate diff --git a/hw/bsp/espressif/boards/family.c b/hw/bsp/espressif/boards/family.c index 325e9ab0f..5599d1504 100644 --- a/hw/bsp/espressif/boards/family.c +++ b/hw/bsp/espressif/boards/family.c @@ -33,7 +33,7 @@ #include "hal/usb_hal.h" #include "soc/usb_periph.h" -#include "driver/rmt.h" +#include "driver/gpio.h" #include "driver/uart.h" #if ESP_IDF_VERSION_MAJOR > 4 @@ -48,7 +48,7 @@ #ifdef NEOPIXEL_PIN #include "led_strip.h" -static led_strip_t* strip; +static led_strip_handle_t led_strip; #endif #if CFG_TUH_ENABLED && CFG_TUH_MAX3421 @@ -85,15 +85,23 @@ void board_init(void) { #endif // WS2812 Neopixel driver with RMT peripheral - rmt_config_t config = RMT_DEFAULT_CONFIG_TX(NEOPIXEL_PIN, RMT_CHANNEL_0); - config.clk_div = 2; // set counter clock to 40MHz + led_strip_rmt_config_t rmt_config = { + .clk_src = RMT_CLK_SRC_DEFAULT, // different clock source can lead to different power consumption + .resolution_hz = 10 * 1000 * 1000, // RMT counter clock frequency, default = 10 Mhz + .flags.with_dma = false, // DMA feature is available on ESP target like ESP32-S3 + }; - rmt_config(&config); - rmt_driver_install(config.channel, 0, 0); + led_strip_config_t strip_config = { + .strip_gpio_num = NEOPIXEL_PIN, // The GPIO that connected to the LED strip's data line + .max_leds = 1, // The number of LEDs in the strip, + .led_pixel_format = LED_PIXEL_FORMAT_GRB, // Pixel format of your LED strip + .led_model = LED_MODEL_WS2812, // LED strip model + .flags.invert_out = false, // whether to invert the output signal + }; - led_strip_config_t strip_config = LED_STRIP_DEFAULT_CONFIG(1, (led_strip_dev_t) config.channel); - strip = led_strip_new_rmt_ws2812(&strip_config); - strip->clear(strip, 100); // off led + ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip)); + + led_strip_clear(led_strip); // off #endif // Button @@ -158,8 +166,8 @@ size_t board_get_unique_id(uint8_t id[], size_t max_len) { void board_led_write(bool state) { #ifdef NEOPIXEL_PIN - strip->set_pixel(strip, 0, state ? 0x08 : 0x00, 0x00, 0x00); - strip->refresh(strip, 100); + led_strip_set_pixel(led_strip, 0, state ? 0x08 : 0x00, 0x00, 0x00); + led_strip_refresh(led_strip); #endif } diff --git a/hw/bsp/espressif/components/led_strip/CHANGELOG.md b/hw/bsp/espressif/components/led_strip/CHANGELOG.md new file mode 100644 index 000000000..51c0cd30c --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/CHANGELOG.md @@ -0,0 +1,38 @@ +## 2.5.0 + +- Enabled support for IDF4.4 and above + - with RMT backend only +- Added API `led_strip_set_pixel_hsv` + +## 2.4.0 + +- Support configurable SPI mode to control leds + - recommend enabling DMA when using SPI mode + +## 2.3.0 + +- Support configurable RMT channel size by setting `mem_block_symbols` + +## 2.2.0 + +- Support for 4 components RGBW leds (SK6812): + - in led_strip_config_t new fields + led_pixel_format, controlling byte format (LED_PIXEL_FORMAT_GRB, LED_PIXEL_FORMAT_GRBW) + led_model, used to configure bit timing (LED_MODEL_WS2812, LED_MODEL_SK6812) + - new API led_strip_set_pixel_rgbw + - new interface type set_pixel_rgbw + +## 2.1.0 + +- Support DMA feature, which offloads the CPU by a lot when it comes to drive a bunch of LEDs +- Support various RMT clock sources +- Acquire and release the power management lock before and after each refresh +- New driver flag: `invert_out` which can invert the led control signal by hardware + +## 2.0.0 + +- Reimplemented the driver using the new RMT driver (`driver/rmt_tx.h`) + +## 1.0.0 + +- Initial driver version, based on the legacy RMT driver (`driver/rmt.h`) diff --git a/hw/bsp/espressif/components/led_strip/CMakeLists.txt b/hw/bsp/espressif/components/led_strip/CMakeLists.txt index 8266c5a1c..15de610cc 100644 --- a/hw/bsp/espressif/components/led_strip/CMakeLists.txt +++ b/hw/bsp/espressif/components/led_strip/CMakeLists.txt @@ -1,7 +1,22 @@ -set(component_srcs "src/led_strip_rmt_ws2812.c") +include($ENV{IDF_PATH}/tools/cmake/version.cmake) -idf_component_register(SRCS "${component_srcs}" - INCLUDE_DIRS "include" - PRIV_INCLUDE_DIRS "" - PRIV_REQUIRES "driver" - REQUIRES "") +set(srcs "src/led_strip_api.c") + +if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER_EQUAL "5.0") + if(CONFIG_SOC_RMT_SUPPORTED) + list(APPEND srcs "src/led_strip_rmt_dev.c" "src/led_strip_rmt_encoder.c") + endif() +else() + list(APPEND srcs "src/led_strip_rmt_dev_idf4.c") +endif() + +# the SPI backend driver relies on something that was added in IDF 5.1 +if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER_EQUAL "5.1") + if(CONFIG_SOC_GPSPI_SUPPORTED) + list(APPEND srcs "src/led_strip_spi_dev.c") + endif() +endif() + +idf_component_register(SRCS ${srcs} + INCLUDE_DIRS "include" "interface" + REQUIRES "driver") diff --git a/hw/bsp/espressif/components/led_strip/LICENSE b/hw/bsp/espressif/components/led_strip/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/hw/bsp/espressif/components/led_strip/README.md b/hw/bsp/espressif/components/led_strip/README.md new file mode 100644 index 000000000..543d29642 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/README.md @@ -0,0 +1,97 @@ +# LED Strip Driver + +[![Component Registry](https://components.espressif.com/components/espressif/led_strip/badge.svg)](https://components.espressif.com/components/espressif/led_strip) + +This driver is designed for addressable LEDs like [WS2812](http://www.world-semi.com/Certifications/WS2812B.html), where each LED is controlled by a single data line. + +## Backend Controllers + +### The [RMT](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/rmt.html) Peripheral + +This is the most economical way to drive the LEDs because it only consumes one RMT channel, leaving other channels free to use. However, the memory usage increases dramatically with the number of LEDs. If the RMT hardware can't be assist by DMA, the driver will going into interrupt very frequently, thus result in a high CPU usage. What's worse, if the RMT interrupt is delayed or not serviced in time (e.g. if Wi-Fi interrupt happens on the same CPU core), the RMT transaction will be corrupted and the LEDs will display incorrect colors. If you want to use RMT to drive a large number of LEDs, you'd better to enable the DMA feature if possible [^1]. + +#### Allocate LED Strip Object with RMT Backend + +```c +#define BLINK_GPIO 0 + +led_strip_handle_t led_strip; + +/* LED strip initialization with the GPIO and pixels number*/ +led_strip_config_t strip_config = { + .strip_gpio_num = BLINK_GPIO, // The GPIO that connected to the LED strip's data line + .max_leds = 1, // The number of LEDs in the strip, + .led_pixel_format = LED_PIXEL_FORMAT_GRB, // Pixel format of your LED strip + .led_model = LED_MODEL_WS2812, // LED strip model + .flags.invert_out = false, // whether to invert the output signal (useful when your hardware has a level inverter) +}; + +led_strip_rmt_config_t rmt_config = { +#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) + .rmt_channel = 0, +#else + .clk_src = RMT_CLK_SRC_DEFAULT, // different clock source can lead to different power consumption + .resolution_hz = 10 * 1000 * 1000, // 10MHz + .flags.with_dma = false, // whether to enable the DMA feature +#endif +}; +ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip)); +``` + +You can create multiple LED strip objects with different GPIOs and pixel numbers. The backend driver will automatically allocate the RMT channel for you if there is more available. + +### The [SPI](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/spi_master.html) Peripheral + +SPI peripheral can also be used to generate the timing required by the LED strip. However this backend is not as economical as the RMT one, because it will take up the whole **bus**, unlike the RMT just takes one **channel**. You **CAN'T** connect other devices to the same SPI bus if it's been used by the led_strip, because the led_strip doesn't have the concept of "Chip Select". + +Please note, the SPI backend has a dependency of **ESP-IDF >= 5.1** + +#### Allocate LED Strip Object with SPI Backend + +```c +#define BLINK_GPIO 0 + +led_strip_handle_t led_strip; + +/* LED strip initialization with the GPIO and pixels number*/ +led_strip_config_t strip_config = { + .strip_gpio_num = BLINK_GPIO, // The GPIO that connected to the LED strip's data line + .max_leds = 1, // The number of LEDs in the strip, + .led_pixel_format = LED_PIXEL_FORMAT_GRB, // Pixel format of your LED strip + .led_model = LED_MODEL_WS2812, // LED strip model + .flags.invert_out = false, // whether to invert the output signal (useful when your hardware has a level inverter) +}; + +led_strip_spi_config_t spi_config = { + .clk_src = SPI_CLK_SRC_DEFAULT, // different clock source can lead to different power consumption + .flags.with_dma = true, // Using DMA can improve performance and help drive more LEDs + .spi_bus = SPI2_HOST, // SPI bus ID +}; +ESP_ERROR_CHECK(led_strip_new_spi_device(&strip_config, &spi_config, &led_strip)); +``` + +The number of LED strip objects can be created depends on how many free SPI buses are free to use in your project. + +## FAQ + +* Which led_strip backend should I choose? + * It depends on your application requirement and target chip's ability. + + ```mermaid + flowchart LR + A{Is RMT supported?} + A --> |No| B[SPI backend] + B --> C{Does the led strip has \n a larger number of LEDs?} + C --> |No| D[Don't have to enable the DMA of the backend] + C --> |Yes| E[Enable the DMA of the backend] + A --> |Yes| F{Does the led strip has \n a larger number of LEDs?} + F --> |Yes| G{Does RMT support DMA?} + G --> |Yes| E + G --> |No| B + F --> |No| H[RMT backend] --> D + ``` + +* How to set the brightness of the LED strip? + * You can tune the brightness by scaling the value of each R-G-B element with a **same** factor. But pay attention to the overflow of the value. + +[^1]: The RMT DMA feature is not available on all ESP chips. Please check the data sheet before using it. diff --git a/hw/bsp/espressif/components/led_strip/api.md b/hw/bsp/espressif/components/led_strip/api.md new file mode 100644 index 000000000..6581d6604 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/api.md @@ -0,0 +1,454 @@ +# API Reference + +## Header files + +- [include/led_strip.h](#file-includeled_striph) +- [include/led_strip_rmt.h](#file-includeled_strip_rmth) +- [include/led_strip_spi.h](#file-includeled_strip_spih) +- [include/led_strip_types.h](#file-includeled_strip_typesh) +- [interface/led_strip_interface.h](#file-interfaceled_strip_interfaceh) + +## File include/led_strip.h + +## Functions + +| Type | Name | +| ---: | :--- | +| esp\_err\_t | [**led\_strip\_clear**](#function-led_strip_clear) ([**led\_strip\_handle\_t**](#struct-led_strip_t) strip)
_Clear LED strip (turn off all LEDs)_ | +| esp\_err\_t | [**led\_strip\_del**](#function-led_strip_del) ([**led\_strip\_handle\_t**](#struct-led_strip_t) strip)
_Free LED strip resources._ | +| esp\_err\_t | [**led\_strip\_refresh**](#function-led_strip_refresh) ([**led\_strip\_handle\_t**](#struct-led_strip_t) strip)
_Refresh memory colors to LEDs._ | +| esp\_err\_t | [**led\_strip\_set\_pixel**](#function-led_strip_set_pixel) ([**led\_strip\_handle\_t**](#struct-led_strip_t) strip, uint32\_t index, uint32\_t red, uint32\_t green, uint32\_t blue)
_Set RGB for a specific pixel._ | +| esp\_err\_t | [**led\_strip\_set\_pixel\_hsv**](#function-led_strip_set_pixel_hsv) ([**led\_strip\_handle\_t**](#struct-led_strip_t) strip, uint32\_t index, uint16\_t hue, uint8\_t saturation, uint8\_t value)
_Set HSV for a specific pixel._ | +| esp\_err\_t | [**led\_strip\_set\_pixel\_rgbw**](#function-led_strip_set_pixel_rgbw) ([**led\_strip\_handle\_t**](#struct-led_strip_t) strip, uint32\_t index, uint32\_t red, uint32\_t green, uint32\_t blue, uint32\_t white)
_Set RGBW for a specific pixel._ | + +## Functions Documentation + +### function `led_strip_clear` + +_Clear LED strip (turn off all LEDs)_ + +```c +esp_err_t led_strip_clear ( + led_strip_handle_t strip +) +``` + +**Parameters:** + +- `strip` LED strip + +**Returns:** + +- ESP\_OK: Clear LEDs successfully +- ESP\_FAIL: Clear LEDs failed because some other error occurred + +### function `led_strip_del` + +_Free LED strip resources._ + +```c +esp_err_t led_strip_del ( + led_strip_handle_t strip +) +``` + +**Parameters:** + +- `strip` LED strip + +**Returns:** + +- ESP\_OK: Free resources successfully +- ESP\_FAIL: Free resources failed because error occurred + +### function `led_strip_refresh` + +_Refresh memory colors to LEDs._ + +```c +esp_err_t led_strip_refresh ( + led_strip_handle_t strip +) +``` + +**Parameters:** + +- `strip` LED strip + +**Returns:** + +- ESP\_OK: Refresh successfully +- ESP\_FAIL: Refresh failed because some other error occurred + +**Note:** + +: After updating the LED colors in the memory, a following invocation of this API is needed to flush colors to strip. + +### function `led_strip_set_pixel` + +_Set RGB for a specific pixel._ + +```c +esp_err_t led_strip_set_pixel ( + led_strip_handle_t strip, + uint32_t index, + uint32_t red, + uint32_t green, + uint32_t blue +) +``` + +**Parameters:** + +- `strip` LED strip +- `index` index of pixel to set +- `red` red part of color +- `green` green part of color +- `blue` blue part of color + +**Returns:** + +- ESP\_OK: Set RGB for a specific pixel successfully +- ESP\_ERR\_INVALID\_ARG: Set RGB for a specific pixel failed because of invalid parameters +- ESP\_FAIL: Set RGB for a specific pixel failed because other error occurred + +### function `led_strip_set_pixel_hsv` + +_Set HSV for a specific pixel._ + +```c +esp_err_t led_strip_set_pixel_hsv ( + led_strip_handle_t strip, + uint32_t index, + uint16_t hue, + uint8_t saturation, + uint8_t value +) +``` + +**Parameters:** + +- `strip` LED strip +- `index` index of pixel to set +- `hue` hue part of color (0 - 360) +- `saturation` saturation part of color (0 - 255) +- `value` value part of color (0 - 255) + +**Returns:** + +- ESP\_OK: Set HSV color for a specific pixel successfully +- ESP\_ERR\_INVALID\_ARG: Set HSV color for a specific pixel failed because of an invalid argument +- ESP\_FAIL: Set HSV color for a specific pixel failed because other error occurred + +### function `led_strip_set_pixel_rgbw` + +_Set RGBW for a specific pixel._ + +```c +esp_err_t led_strip_set_pixel_rgbw ( + led_strip_handle_t strip, + uint32_t index, + uint32_t red, + uint32_t green, + uint32_t blue, + uint32_t white +) +``` + +**Note:** + +Only call this function if your led strip does have the white component (e.g. SK6812-RGBW) + +**Note:** + +Also see `led_strip_set_pixel` if you only want to specify the RGB part of the color and bypass the white component + +**Parameters:** + +- `strip` LED strip +- `index` index of pixel to set +- `red` red part of color +- `green` green part of color +- `blue` blue part of color +- `white` separate white component + +**Returns:** + +- ESP\_OK: Set RGBW color for a specific pixel successfully +- ESP\_ERR\_INVALID\_ARG: Set RGBW color for a specific pixel failed because of an invalid argument +- ESP\_FAIL: Set RGBW color for a specific pixel failed because other error occurred + +## File include/led_strip_rmt.h + +## Structures and Types + +| Type | Name | +| ---: | :--- | +| struct | [**led\_strip\_rmt\_config\_t**](#struct-led_strip_rmt_config_t)
_LED Strip RMT specific configuration._ | + +## Functions + +| Type | Name | +| ---: | :--- | +| esp\_err\_t | [**led\_strip\_new\_rmt\_device**](#function-led_strip_new_rmt_device) (const [**led\_strip\_config\_t**](#struct-led_strip_config_t) \*led\_config, const [**led\_strip\_rmt\_config\_t**](#struct-led_strip_rmt_config_t) \*rmt\_config, [**led\_strip\_handle\_t**](#struct-led_strip_t) \*ret\_strip)
_Create LED strip based on RMT TX channel._ | + +## Structures and Types Documentation + +### struct `led_strip_rmt_config_t` + +_LED Strip RMT specific configuration._ + +Variables: + +- rmt\_clock\_source\_t clk_src
RMT clock source + +- struct [**led\_strip\_rmt\_config\_t**](#struct-led_strip_rmt_config_t) flags
Extra driver flags + +- size\_t mem_block_symbols
How many RMT symbols can one RMT channel hold at one time. Set to 0 will fallback to use the default size. + +- uint32\_t resolution_hz
RMT tick resolution, if set to zero, a default resolution (10MHz) will be applied + +- uint32\_t with_dma
Use DMA to transmit data + +## Functions Documentation + +### function `led_strip_new_rmt_device` + +_Create LED strip based on RMT TX channel._ + +```c +esp_err_t led_strip_new_rmt_device ( + const led_strip_config_t *led_config, + const led_strip_rmt_config_t *rmt_config, + led_strip_handle_t *ret_strip +) +``` + +**Parameters:** + +- `led_config` LED strip configuration +- `rmt_config` RMT specific configuration +- `ret_strip` Returned LED strip handle + +**Returns:** + +- ESP\_OK: create LED strip handle successfully +- ESP\_ERR\_INVALID\_ARG: create LED strip handle failed because of invalid argument +- ESP\_ERR\_NO\_MEM: create LED strip handle failed because of out of memory +- ESP\_FAIL: create LED strip handle failed because some other error + +## File include/led_strip_spi.h + +## Structures and Types + +| Type | Name | +| ---: | :--- | +| struct | [**led\_strip\_spi\_config\_t**](#struct-led_strip_spi_config_t)
_LED Strip SPI specific configuration._ | + +## Functions + +| Type | Name | +| ---: | :--- | +| esp\_err\_t | [**led\_strip\_new\_spi\_device**](#function-led_strip_new_spi_device) (const [**led\_strip\_config\_t**](#struct-led_strip_config_t) \*led\_config, const [**led\_strip\_spi\_config\_t**](#struct-led_strip_spi_config_t) \*spi\_config, [**led\_strip\_handle\_t**](#struct-led_strip_t) \*ret\_strip)
_Create LED strip based on SPI MOSI channel._ | + +## Structures and Types Documentation + +### struct `led_strip_spi_config_t` + +_LED Strip SPI specific configuration._ + +Variables: + +- spi\_clock\_source\_t clk_src
SPI clock source + +- struct [**led\_strip\_spi\_config\_t**](#struct-led_strip_spi_config_t) flags
Extra driver flags + +- spi\_host\_device\_t spi_bus
SPI bus ID. Which buses are available depends on the specific chip + +- uint32\_t with_dma
Use DMA to transmit data + +## Functions Documentation + +### function `led_strip_new_spi_device` + +_Create LED strip based on SPI MOSI channel._ + +```c +esp_err_t led_strip_new_spi_device ( + const led_strip_config_t *led_config, + const led_strip_spi_config_t *spi_config, + led_strip_handle_t *ret_strip +) +``` + +**Note:** + +Although only the MOSI line is used for generating the signal, the whole SPI bus can't be used for other purposes. + +**Parameters:** + +- `led_config` LED strip configuration +- `spi_config` SPI specific configuration +- `ret_strip` Returned LED strip handle + +**Returns:** + +- ESP\_OK: create LED strip handle successfully +- ESP\_ERR\_INVALID\_ARG: create LED strip handle failed because of invalid argument +- ESP\_ERR\_NOT\_SUPPORTED: create LED strip handle failed because of unsupported configuration +- ESP\_ERR\_NO\_MEM: create LED strip handle failed because of out of memory +- ESP\_FAIL: create LED strip handle failed because some other error + +## File include/led_strip_types.h + +## Structures and Types + +| Type | Name | +| ---: | :--- | +| enum | [**led\_model\_t**](#enum-led_model_t)
_LED strip model._ | +| enum | [**led\_pixel\_format\_t**](#enum-led_pixel_format_t)
_LED strip pixel format._ | +| struct | [**led\_strip\_config\_t**](#struct-led_strip_config_t)
_LED Strip Configuration._ | +| typedef struct [**led\_strip\_t**](#struct-led_strip_t) \* | [**led\_strip\_handle\_t**](#typedef-led_strip_handle_t)
_LED strip handle._ | + +## Structures and Types Documentation + +### enum `led_model_t` + +_LED strip model._ + +```c +enum led_model_t { + LED_MODEL_WS2812, + LED_MODEL_SK6812, + LED_MODEL_INVALID +}; +``` + +**Note:** + +Different led model may have different timing parameters, so we need to distinguish them. + +### enum `led_pixel_format_t` + +_LED strip pixel format._ + +```c +enum led_pixel_format_t { + LED_PIXEL_FORMAT_GRB, + LED_PIXEL_FORMAT_GRBW, + LED_PIXEL_FORMAT_INVALID +}; +``` + +### struct `led_strip_config_t` + +_LED Strip Configuration._ + +Variables: + +- struct [**led\_strip\_config\_t**](#struct-led_strip_config_t) flags
Extra driver flags + +- uint32\_t invert_out
Invert output signal + +- led\_model\_t led_model
LED model + +- led\_pixel\_format\_t led_pixel_format
LED pixel format + +- uint32\_t max_leds
Maximum LEDs in a single strip + +- int strip_gpio_num
GPIO number that used by LED strip + +### typedef `led_strip_handle_t` + +_LED strip handle._ + +```c +typedef struct led_strip_t* led_strip_handle_t; +``` + +## File interface/led_strip_interface.h + +## Structures and Types + +| Type | Name | +| ---: | :--- | +| struct | [**led\_strip\_t**](#struct-led_strip_t)
_LED strip interface definition._ | +| typedef struct [**led\_strip\_t**](#struct-led_strip_t) | [**led\_strip\_t**](#typedef-led_strip_t)
| + +## Structures and Types Documentation + +### struct `led_strip_t` + +_LED strip interface definition._ + +Variables: + +- esp\_err\_t(\* clear
_Clear LED strip (turn off all LEDs)_
**Parameters:** + +- `strip` LED strip +- `timeout_ms` timeout value for clearing task + +**Returns:** + +- ESP\_OK: Clear LEDs successfully +- ESP\_FAIL: Clear LEDs failed because some other error occurred + +- esp\_err\_t(\* del
_Free LED strip resources._
**Parameters:** + +- `strip` LED strip + +**Returns:** + +- ESP\_OK: Free resources successfully +- ESP\_FAIL: Free resources failed because error occurred + +- esp\_err\_t(\* refresh
_Refresh memory colors to LEDs._
**Parameters:** + +- `strip` LED strip +- `timeout_ms` timeout value for refreshing task + +**Returns:** + +- ESP\_OK: Refresh successfully +- ESP\_FAIL: Refresh failed because some other error occurred + +**Note:** + +: After updating the LED colors in the memory, a following invocation of this API is needed to flush colors to strip. + +- esp\_err\_t(\* set_pixel
_Set RGB for a specific pixel._
**Parameters:** + +- `strip` LED strip +- `index` index of pixel to set +- `red` red part of color +- `green` green part of color +- `blue` blue part of color + +**Returns:** + +- ESP\_OK: Set RGB for a specific pixel successfully +- ESP\_ERR\_INVALID\_ARG: Set RGB for a specific pixel failed because of invalid parameters +- ESP\_FAIL: Set RGB for a specific pixel failed because other error occurred + +- esp\_err\_t(\* set_pixel_rgbw
_Set RGBW for a specific pixel. Similar to_ `set_pixel`_but also set the white component._
**Parameters:** + +- `strip` LED strip +- `index` index of pixel to set +- `red` red part of color +- `green` green part of color +- `blue` blue part of color +- `white` separate white component + +**Returns:** + +- ESP\_OK: Set RGBW color for a specific pixel successfully +- ESP\_ERR\_INVALID\_ARG: Set RGBW color for a specific pixel failed because of an invalid argument +- ESP\_FAIL: Set RGBW color for a specific pixel failed because other error occurred + +### typedef `led_strip_t` + +```c +typedef struct led_strip_t led_strip_t; +``` + +Type of LED strip diff --git a/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/CMakeLists.txt b/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/CMakeLists.txt new file mode 100644 index 000000000..923c46310 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/CMakeLists.txt @@ -0,0 +1,9 @@ +# For more information about build system see +# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html +# The following five lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +set(IDF_TARGET "esp32s3") +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(led_strip_rmt_ws2812) diff --git a/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/README.md b/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/README.md new file mode 100644 index 000000000..ad52235d5 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/README.md @@ -0,0 +1,31 @@ +# LED Strip Example (RMT backend + WS2812) + +This example demonstrates how to blink the WS2812 LED using the [led_strip](https://components.espressif.com/component/espressif/led_strip) component. + +## How to Use Example + +### Hardware Required + +* A development board with Espressif SoC +* A USB cable for Power supply and programming +* WS2812 LED strip + +### Configure the Example + +Before project configuration and build, be sure to set the correct chip target using `idf.py set-target `. Then assign the proper GPIO in the [source file](main/led_strip_rmt_ws2812_main.c). If your led strip has multiple LEDs, don't forget update the number. + +### Build and Flash + +Run `idf.py -p PORT build flash monitor` to build, flash and monitor the project. + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects. + +## Example Output + +```text +I (299) gpio: GPIO[8]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 +I (309) example: Created LED strip object with RMT backend +I (309) example: Start blinking LED strip +``` 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 new file mode 100644 index 000000000..97840a153 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/dependencies.lock @@ -0,0 +1,15 @@ +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/espressif/components/led_strip/examples/led_strip_rmt_ws2812/main/CMakeLists.txt b/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/main/CMakeLists.txt new file mode 100644 index 000000000..37b9c1458 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "led_strip_rmt_ws2812_main.c" + INCLUDE_DIRS ".") diff --git a/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/main/idf_component.yml b/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/main/idf_component.yml new file mode 100644 index 000000000..916c366c7 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/main/idf_component.yml @@ -0,0 +1,5 @@ +## IDF Component Manager Manifest File +dependencies: + espressif/led_strip: + version: '^2' + override_path: '../../../' diff --git a/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/main/led_strip_rmt_ws2812_main.c b/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/main/led_strip_rmt_ws2812_main.c new file mode 100644 index 000000000..4b20a5958 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/main/led_strip_rmt_ws2812_main.c @@ -0,0 +1,75 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "led_strip.h" +#include "esp_log.h" +#include "esp_err.h" + +// GPIO assignment +#define LED_STRIP_BLINK_GPIO 48 +// Numbers of the LED in the strip +#define LED_STRIP_LED_NUMBERS 1 +// 10MHz resolution, 1 tick = 0.1us (led strip needs a high resolution) +#define LED_STRIP_RMT_RES_HZ (10 * 1000 * 1000) + +static const char *TAG = "example"; + +led_strip_handle_t configure_led(void) +{ + // LED strip general initialization, according to your led board design + led_strip_config_t strip_config = { + .strip_gpio_num = LED_STRIP_BLINK_GPIO, // The GPIO that connected to the LED strip's data line + .max_leds = LED_STRIP_LED_NUMBERS, // The number of LEDs in the strip, + .led_pixel_format = LED_PIXEL_FORMAT_GRB, // Pixel format of your LED strip + .led_model = LED_MODEL_WS2812, // LED strip model + .flags.invert_out = false, // whether to invert the output signal + }; + + // LED strip backend configuration: RMT + led_strip_rmt_config_t rmt_config = { +#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) + .rmt_channel = 0, +#else + .clk_src = RMT_CLK_SRC_DEFAULT, // different clock source can lead to different power consumption + .resolution_hz = LED_STRIP_RMT_RES_HZ, // RMT counter clock frequency + .flags.with_dma = false, // DMA feature is available on ESP target like ESP32-S3 +#endif + }; + + // LED Strip object handle + led_strip_handle_t led_strip; + ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip)); + ESP_LOGI(TAG, "Created LED strip object with RMT backend"); + return led_strip; +} + +void app_main(void) +{ + led_strip_handle_t led_strip = configure_led(); + bool led_on_off = false; + + ESP_LOGI(TAG, "Start blinking LED strip"); + while (1) { + if (led_on_off) { + /* Set the LED pixel using RGB from 0 (0%) to 255 (100%) for each color */ + for (int i = 0; i < LED_STRIP_LED_NUMBERS; i++) { + ESP_ERROR_CHECK(led_strip_set_pixel(led_strip, i, 5, 5, 5)); + } + /* Refresh the strip to send data */ + ESP_ERROR_CHECK(led_strip_refresh(led_strip)); + ESP_LOGI(TAG, "LED ON!"); + } else { + /* Set all LED off to clear all pixels */ + ESP_ERROR_CHECK(led_strip_clear(led_strip)); + ESP_LOGI(TAG, "LED OFF!"); + } + + led_on_off = !led_on_off; + vTaskDelay(pdMS_TO_TICKS(500)); + } +} diff --git a/hw/bsp/espressif/components/led_strip/idf_component.yml b/hw/bsp/espressif/components/led_strip/idf_component.yml new file mode 100644 index 000000000..1fd9b83ee --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/idf_component.yml @@ -0,0 +1,5 @@ +version: "2.5.2" +description: Driver for Addressable LED Strip (WS2812, etc) +url: https://github.com/espressif/idf-extra-components/tree/master/led_strip +dependencies: + idf: ">=4.4" diff --git a/hw/bsp/espressif/components/led_strip/include/led_strip.h b/hw/bsp/espressif/components/led_strip/include/led_strip.h index a9dffc325..38711744a 100644 --- a/hw/bsp/espressif/components/led_strip/include/led_strip.h +++ b/hw/bsp/espressif/components/led_strip/include/led_strip.h @@ -1,125 +1,110 @@ -// Copyright 2019 Espressif Systems (Shanghai) PTE LTD -// -// 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. +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once +#include +#include "esp_err.h" +#include "led_strip_rmt.h" +#include "esp_idf_version.h" + +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0) +#include "led_strip_spi.h" +#endif + #ifdef __cplusplus extern "C" { #endif -#include "esp_err.h" - /** -* @brief LED Strip Type -* -*/ -typedef struct led_strip_s led_strip_t; - -/** -* @brief LED Strip Device Type -* -*/ -typedef void *led_strip_dev_t; - -/** -* @brief Declare of LED Strip Type -* -*/ -struct led_strip_s { - /** - * @brief Set RGB for a specific pixel - * - * @param strip: LED strip - * @param index: index of pixel to set - * @param red: red part of color - * @param green: green part of color - * @param blue: blue part of color - * - * @return - * - ESP_OK: Set RGB for a specific pixel successfully - * - ESP_ERR_INVALID_ARG: Set RGB for a specific pixel failed because of invalid parameters - * - ESP_FAIL: Set RGB for a specific pixel failed because other error occurred - */ - esp_err_t (*set_pixel)(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue); - - /** - * @brief Refresh memory colors to LEDs - * - * @param strip: LED strip - * @param timeout_ms: timeout value for refreshing task - * - * @return - * - ESP_OK: Refresh successfully - * - ESP_ERR_TIMEOUT: Refresh failed because of timeout - * - ESP_FAIL: Refresh failed because some other error occurred - * - * @note: - * After updating the LED colors in the memory, a following invocation of this API is needed to flush colors to strip. - */ - esp_err_t (*refresh)(led_strip_t *strip, uint32_t timeout_ms); - - /** - * @brief Clear LED strip (turn off all LEDs) - * - * @param strip: LED strip - * @param timeout_ms: timeout value for clearing task - * - * @return - * - ESP_OK: Clear LEDs successfully - * - ESP_ERR_TIMEOUT: Clear LEDs failed because of timeout - * - ESP_FAIL: Clear LEDs failed because some other error occurred - */ - esp_err_t (*clear)(led_strip_t *strip, uint32_t timeout_ms); - - /** - * @brief Free LED strip resources - * - * @param strip: LED strip - * - * @return - * - ESP_OK: Free resources successfully - * - ESP_FAIL: Free resources failed because error occurred - */ - esp_err_t (*del)(led_strip_t *strip); -}; - -/** -* @brief LED Strip Configuration Type -* -*/ -typedef struct { - uint32_t max_leds; /*!< Maximum LEDs in a single strip */ - led_strip_dev_t dev; /*!< LED strip device (e.g. RMT channel, PWM channel, etc) */ -} led_strip_config_t; - -/** - * @brief Default configuration for LED strip + * @brief Set RGB for a specific pixel * + * @param strip: LED strip + * @param index: index of pixel to set + * @param red: red part of color + * @param green: green part of color + * @param blue: blue part of color + * + * @return + * - ESP_OK: Set RGB for a specific pixel successfully + * - ESP_ERR_INVALID_ARG: Set RGB for a specific pixel failed because of invalid parameters + * - ESP_FAIL: Set RGB for a specific pixel failed because other error occurred */ -#define LED_STRIP_DEFAULT_CONFIG(number, dev_hdl) \ - { \ - .max_leds = number, \ - .dev = dev_hdl, \ - } +esp_err_t led_strip_set_pixel(led_strip_handle_t strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue); /** -* @brief Install a new ws2812 driver (based on RMT peripheral) -* -* @param config: LED strip configuration -* @return -* LED strip instance or NULL -*/ -led_strip_t *led_strip_new_rmt_ws2812(const led_strip_config_t *config); + * @brief Set RGBW for a specific pixel + * + * @note Only call this function if your led strip does have the white component (e.g. SK6812-RGBW) + * @note Also see `led_strip_set_pixel` if you only want to specify the RGB part of the color and bypass the white component + * + * @param strip: LED strip + * @param index: index of pixel to set + * @param red: red part of color + * @param green: green part of color + * @param blue: blue part of color + * @param white: separate white component + * + * @return + * - ESP_OK: Set RGBW color for a specific pixel successfully + * - ESP_ERR_INVALID_ARG: Set RGBW color for a specific pixel failed because of an invalid argument + * - ESP_FAIL: Set RGBW color for a specific pixel failed because other error occurred + */ +esp_err_t led_strip_set_pixel_rgbw(led_strip_handle_t strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue, uint32_t white); + +/** + * @brief Set HSV for a specific pixel + * + * @param strip: LED strip + * @param index: index of pixel to set + * @param hue: hue part of color (0 - 360) + * @param saturation: saturation part of color (0 - 255) + * @param value: value part of color (0 - 255) + * + * @return + * - ESP_OK: Set HSV color for a specific pixel successfully + * - ESP_ERR_INVALID_ARG: Set HSV color for a specific pixel failed because of an invalid argument + * - ESP_FAIL: Set HSV color for a specific pixel failed because other error occurred + */ +esp_err_t led_strip_set_pixel_hsv(led_strip_handle_t strip, uint32_t index, uint16_t hue, uint8_t saturation, uint8_t value); + +/** + * @brief Refresh memory colors to LEDs + * + * @param strip: LED strip + * + * @return + * - ESP_OK: Refresh successfully + * - ESP_FAIL: Refresh failed because some other error occurred + * + * @note: + * After updating the LED colors in the memory, a following invocation of this API is needed to flush colors to strip. + */ +esp_err_t led_strip_refresh(led_strip_handle_t strip); + +/** + * @brief Clear LED strip (turn off all LEDs) + * + * @param strip: LED strip + * + * @return + * - ESP_OK: Clear LEDs successfully + * - ESP_FAIL: Clear LEDs failed because some other error occurred + */ +esp_err_t led_strip_clear(led_strip_handle_t strip); + +/** + * @brief Free LED strip resources + * + * @param strip: LED strip + * + * @return + * - ESP_OK: Free resources successfully + * - ESP_FAIL: Free resources failed because error occurred + */ +esp_err_t led_strip_del(led_strip_handle_t strip); #ifdef __cplusplus } diff --git a/hw/bsp/espressif/components/led_strip/include/led_strip_rmt.h b/hw/bsp/espressif/components/led_strip/include/led_strip_rmt.h new file mode 100644 index 000000000..b575aeaba --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/include/led_strip_rmt.h @@ -0,0 +1,53 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include "esp_err.h" +#include "led_strip_types.h" +#include "esp_idf_version.h" + +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) +#include "driver/rmt_types.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief LED Strip RMT specific configuration + */ +typedef struct { +#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) + uint8_t rmt_channel; /*!< Specify the channel number, the legacy RMT driver doesn't support channel allocator */ +#else // new driver supports specify the clock source and clock resolution + rmt_clock_source_t clk_src; /*!< RMT clock source */ + uint32_t resolution_hz; /*!< RMT tick resolution, if set to zero, a default resolution (10MHz) will be applied */ +#endif + size_t mem_block_symbols; /*!< How many RMT symbols can one RMT channel hold at one time. Set to 0 will fallback to use the default size. */ + struct { + uint32_t with_dma: 1; /*!< Use DMA to transmit data */ + } flags; /*!< Extra driver flags */ +} led_strip_rmt_config_t; + +/** + * @brief Create LED strip based on RMT TX channel + * + * @param led_config LED strip configuration + * @param rmt_config RMT specific configuration + * @param ret_strip Returned LED strip handle + * @return + * - ESP_OK: create LED strip handle successfully + * - ESP_ERR_INVALID_ARG: create LED strip handle failed because of invalid argument + * - ESP_ERR_NO_MEM: create LED strip handle failed because of out of memory + * - ESP_FAIL: create LED strip handle failed because some other error + */ +esp_err_t led_strip_new_rmt_device(const led_strip_config_t *led_config, const led_strip_rmt_config_t *rmt_config, led_strip_handle_t *ret_strip); + +#ifdef __cplusplus +} +#endif diff --git a/hw/bsp/espressif/components/led_strip/include/led_strip_spi.h b/hw/bsp/espressif/components/led_strip/include/led_strip_spi.h new file mode 100644 index 000000000..eb3524936 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/include/led_strip_spi.h @@ -0,0 +1,46 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include "esp_err.h" +#include "driver/spi_master.h" +#include "led_strip_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief LED Strip SPI specific configuration + */ +typedef struct { + spi_clock_source_t clk_src; /*!< SPI clock source */ + spi_host_device_t spi_bus; /*!< SPI bus ID. Which buses are available depends on the specific chip */ + struct { + uint32_t with_dma: 1; /*!< Use DMA to transmit data */ + } flags; /*!< Extra driver flags */ +} led_strip_spi_config_t; + +/** + * @brief Create LED strip based on SPI MOSI channel + * @note Although only the MOSI line is used for generating the signal, the whole SPI bus can't be used for other purposes. + * + * @param led_config LED strip configuration + * @param spi_config SPI specific configuration + * @param ret_strip Returned LED strip handle + * @return + * - ESP_OK: create LED strip handle successfully + * - ESP_ERR_INVALID_ARG: create LED strip handle failed because of invalid argument + * - ESP_ERR_NOT_SUPPORTED: create LED strip handle failed because of unsupported configuration + * - ESP_ERR_NO_MEM: create LED strip handle failed because of out of memory + * - ESP_FAIL: create LED strip handle failed because some other error + */ +esp_err_t led_strip_new_spi_device(const led_strip_config_t *led_config, const led_strip_spi_config_t *spi_config, led_strip_handle_t *ret_strip); + +#ifdef __cplusplus +} +#endif diff --git a/hw/bsp/espressif/components/led_strip/include/led_strip_types.h b/hw/bsp/espressif/components/led_strip/include/led_strip_types.h new file mode 100644 index 000000000..691f0bc39 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/include/led_strip_types.h @@ -0,0 +1,54 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief LED strip pixel format + */ +typedef enum { + LED_PIXEL_FORMAT_GRB, /*!< Pixel format: GRB */ + LED_PIXEL_FORMAT_GRBW, /*!< Pixel format: GRBW */ + LED_PIXEL_FORMAT_INVALID /*!< Invalid pixel format */ +} led_pixel_format_t; + +/** + * @brief LED strip model + * @note Different led model may have different timing parameters, so we need to distinguish them. + */ +typedef enum { + LED_MODEL_WS2812, /*!< LED strip model: WS2812 */ + LED_MODEL_SK6812, /*!< LED strip model: SK6812 */ + LED_MODEL_INVALID /*!< Invalid LED strip model */ +} led_model_t; + +/** + * @brief LED strip handle + */ +typedef struct led_strip_t *led_strip_handle_t; + +/** + * @brief LED Strip Configuration + */ +typedef struct { + int strip_gpio_num; /*!< GPIO number that used by LED strip */ + uint32_t max_leds; /*!< Maximum LEDs in a single strip */ + led_pixel_format_t led_pixel_format; /*!< LED pixel format */ + led_model_t led_model; /*!< LED model */ + + struct { + uint32_t invert_out: 1; /*!< Invert output signal */ + } flags; /*!< Extra driver flags */ +} led_strip_config_t; + +#ifdef __cplusplus +} +#endif diff --git a/hw/bsp/espressif/components/led_strip/interface/led_strip_interface.h b/hw/bsp/espressif/components/led_strip/interface/led_strip_interface.h new file mode 100644 index 000000000..3de4c2715 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/interface/led_strip_interface.h @@ -0,0 +1,95 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct led_strip_t led_strip_t; /*!< Type of LED strip */ + +/** + * @brief LED strip interface definition + */ +struct led_strip_t { + /** + * @brief Set RGB for a specific pixel + * + * @param strip: LED strip + * @param index: index of pixel to set + * @param red: red part of color + * @param green: green part of color + * @param blue: blue part of color + * + * @return + * - ESP_OK: Set RGB for a specific pixel successfully + * - ESP_ERR_INVALID_ARG: Set RGB for a specific pixel failed because of invalid parameters + * - ESP_FAIL: Set RGB for a specific pixel failed because other error occurred + */ + esp_err_t (*set_pixel)(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue); + + /** + * @brief Set RGBW for a specific pixel. Similar to `set_pixel` but also set the white component + * + * @param strip: LED strip + * @param index: index of pixel to set + * @param red: red part of color + * @param green: green part of color + * @param blue: blue part of color + * @param white: separate white component + * + * @return + * - ESP_OK: Set RGBW color for a specific pixel successfully + * - ESP_ERR_INVALID_ARG: Set RGBW color for a specific pixel failed because of an invalid argument + * - ESP_FAIL: Set RGBW color for a specific pixel failed because other error occurred + */ + esp_err_t (*set_pixel_rgbw)(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue, uint32_t white); + + /** + * @brief Refresh memory colors to LEDs + * + * @param strip: LED strip + * @param timeout_ms: timeout value for refreshing task + * + * @return + * - ESP_OK: Refresh successfully + * - ESP_FAIL: Refresh failed because some other error occurred + * + * @note: + * After updating the LED colors in the memory, a following invocation of this API is needed to flush colors to strip. + */ + esp_err_t (*refresh)(led_strip_t *strip); + + /** + * @brief Clear LED strip (turn off all LEDs) + * + * @param strip: LED strip + * @param timeout_ms: timeout value for clearing task + * + * @return + * - ESP_OK: Clear LEDs successfully + * - ESP_FAIL: Clear LEDs failed because some other error occurred + */ + esp_err_t (*clear)(led_strip_t *strip); + + /** + * @brief Free LED strip resources + * + * @param strip: LED strip + * + * @return + * - ESP_OK: Free resources successfully + * - ESP_FAIL: Free resources failed because error occurred + */ + esp_err_t (*del)(led_strip_t *strip); +}; + +#ifdef __cplusplus +} +#endif diff --git a/hw/bsp/espressif/components/led_strip/src/led_strip_api.c b/hw/bsp/espressif/components/led_strip/src/led_strip_api.c new file mode 100644 index 000000000..6eb86b8f1 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/src/led_strip_api.c @@ -0,0 +1,94 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "esp_log.h" +#include "esp_check.h" +#include "led_strip.h" +#include "led_strip_interface.h" + +static const char *TAG = "led_strip"; + +esp_err_t led_strip_set_pixel(led_strip_handle_t strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue) +{ + ESP_RETURN_ON_FALSE(strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + return strip->set_pixel(strip, index, red, green, blue); +} + +esp_err_t led_strip_set_pixel_hsv(led_strip_handle_t strip, uint32_t index, uint16_t hue, uint8_t saturation, uint8_t value) +{ + ESP_RETURN_ON_FALSE(strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + + uint32_t red = 0; + uint32_t green = 0; + uint32_t blue = 0; + + uint32_t rgb_max = value; + uint32_t rgb_min = rgb_max * (255 - saturation) / 255.0f; + + uint32_t i = hue / 60; + uint32_t diff = hue % 60; + + // RGB adjustment amount by hue + uint32_t rgb_adj = (rgb_max - rgb_min) * diff / 60; + + switch (i) { + case 0: + red = rgb_max; + green = rgb_min + rgb_adj; + blue = rgb_min; + break; + case 1: + red = rgb_max - rgb_adj; + green = rgb_max; + blue = rgb_min; + break; + case 2: + red = rgb_min; + green = rgb_max; + blue = rgb_min + rgb_adj; + break; + case 3: + red = rgb_min; + green = rgb_max - rgb_adj; + blue = rgb_max; + break; + case 4: + red = rgb_min + rgb_adj; + green = rgb_min; + blue = rgb_max; + break; + default: + red = rgb_max; + green = rgb_min; + blue = rgb_max - rgb_adj; + break; + } + + return strip->set_pixel(strip, index, red, green, blue); +} + +esp_err_t led_strip_set_pixel_rgbw(led_strip_handle_t strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue, uint32_t white) +{ + ESP_RETURN_ON_FALSE(strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + return strip->set_pixel_rgbw(strip, index, red, green, blue, white); +} + +esp_err_t led_strip_refresh(led_strip_handle_t strip) +{ + ESP_RETURN_ON_FALSE(strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + return strip->refresh(strip); +} + +esp_err_t led_strip_clear(led_strip_handle_t strip) +{ + ESP_RETURN_ON_FALSE(strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + return strip->clear(strip); +} + +esp_err_t led_strip_del(led_strip_handle_t strip) +{ + ESP_RETURN_ON_FALSE(strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + return strip->del(strip); +} diff --git a/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_dev.c b/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_dev.c new file mode 100644 index 000000000..1cbf0e45a --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_dev.c @@ -0,0 +1,164 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include "esp_log.h" +#include "esp_check.h" +#include "driver/rmt_tx.h" +#include "led_strip.h" +#include "led_strip_interface.h" +#include "led_strip_rmt_encoder.h" + +#define LED_STRIP_RMT_DEFAULT_RESOLUTION 10000000 // 10MHz resolution +#define LED_STRIP_RMT_DEFAULT_TRANS_QUEUE_SIZE 4 +// the memory size of each RMT channel, in words (4 bytes) +#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 +#define LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS 64 +#else +#define LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS 48 +#endif + +static const char *TAG = "led_strip_rmt"; + +typedef struct { + led_strip_t base; + rmt_channel_handle_t rmt_chan; + rmt_encoder_handle_t strip_encoder; + uint32_t strip_len; + uint8_t bytes_per_pixel; + uint8_t pixel_buf[]; +} led_strip_rmt_obj; + +static esp_err_t led_strip_rmt_set_pixel(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue) +{ + led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); + ESP_RETURN_ON_FALSE(index < rmt_strip->strip_len, ESP_ERR_INVALID_ARG, TAG, "index out of maximum number of LEDs"); + uint32_t start = index * rmt_strip->bytes_per_pixel; + // In thr order of GRB, as LED strip like WS2812 sends out pixels in this order + rmt_strip->pixel_buf[start + 0] = green & 0xFF; + rmt_strip->pixel_buf[start + 1] = red & 0xFF; + rmt_strip->pixel_buf[start + 2] = blue & 0xFF; + if (rmt_strip->bytes_per_pixel > 3) { + rmt_strip->pixel_buf[start + 3] = 0; + } + return ESP_OK; +} + +static esp_err_t led_strip_rmt_set_pixel_rgbw(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue, uint32_t white) +{ + led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); + ESP_RETURN_ON_FALSE(index < rmt_strip->strip_len, ESP_ERR_INVALID_ARG, TAG, "index out of maximum number of LEDs"); + ESP_RETURN_ON_FALSE(rmt_strip->bytes_per_pixel == 4, ESP_ERR_INVALID_ARG, TAG, "wrong LED pixel format, expected 4 bytes per pixel"); + uint8_t *buf_start = rmt_strip->pixel_buf + index * 4; + // SK6812 component order is GRBW + *buf_start = green & 0xFF; + *++buf_start = red & 0xFF; + *++buf_start = blue & 0xFF; + *++buf_start = white & 0xFF; + return ESP_OK; +} + +static esp_err_t led_strip_rmt_refresh(led_strip_t *strip) +{ + led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); + rmt_transmit_config_t tx_conf = { + .loop_count = 0, + }; + + ESP_RETURN_ON_ERROR(rmt_enable(rmt_strip->rmt_chan), TAG, "enable RMT channel failed"); + ESP_RETURN_ON_ERROR(rmt_transmit(rmt_strip->rmt_chan, rmt_strip->strip_encoder, rmt_strip->pixel_buf, + rmt_strip->strip_len * rmt_strip->bytes_per_pixel, &tx_conf), TAG, "transmit pixels by RMT failed"); + ESP_RETURN_ON_ERROR(rmt_tx_wait_all_done(rmt_strip->rmt_chan, -1), TAG, "flush RMT channel failed"); + ESP_RETURN_ON_ERROR(rmt_disable(rmt_strip->rmt_chan), TAG, "disable RMT channel failed"); + return ESP_OK; +} + +static esp_err_t led_strip_rmt_clear(led_strip_t *strip) +{ + led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); + // Write zero to turn off all leds + memset(rmt_strip->pixel_buf, 0, rmt_strip->strip_len * rmt_strip->bytes_per_pixel); + return led_strip_rmt_refresh(strip); +} + +static esp_err_t led_strip_rmt_del(led_strip_t *strip) +{ + led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); + ESP_RETURN_ON_ERROR(rmt_del_channel(rmt_strip->rmt_chan), TAG, "delete RMT channel failed"); + ESP_RETURN_ON_ERROR(rmt_del_encoder(rmt_strip->strip_encoder), TAG, "delete strip encoder failed"); + free(rmt_strip); + return ESP_OK; +} + +esp_err_t led_strip_new_rmt_device(const led_strip_config_t *led_config, const led_strip_rmt_config_t *rmt_config, led_strip_handle_t *ret_strip) +{ + led_strip_rmt_obj *rmt_strip = NULL; + esp_err_t ret = ESP_OK; + ESP_GOTO_ON_FALSE(led_config && rmt_config && ret_strip, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); + ESP_GOTO_ON_FALSE(led_config->led_pixel_format < LED_PIXEL_FORMAT_INVALID, ESP_ERR_INVALID_ARG, err, TAG, "invalid led_pixel_format"); + uint8_t bytes_per_pixel = 3; + if (led_config->led_pixel_format == LED_PIXEL_FORMAT_GRBW) { + bytes_per_pixel = 4; + } else if (led_config->led_pixel_format == LED_PIXEL_FORMAT_GRB) { + bytes_per_pixel = 3; + } else { + assert(false); + } + rmt_strip = calloc(1, sizeof(led_strip_rmt_obj) + led_config->max_leds * bytes_per_pixel); + ESP_GOTO_ON_FALSE(rmt_strip, ESP_ERR_NO_MEM, err, TAG, "no mem for rmt strip"); + uint32_t resolution = rmt_config->resolution_hz ? rmt_config->resolution_hz : LED_STRIP_RMT_DEFAULT_RESOLUTION; + + // for backward compatibility, if the user does not set the clk_src, use the default value + rmt_clock_source_t clk_src = RMT_CLK_SRC_DEFAULT; + if (rmt_config->clk_src) { + clk_src = rmt_config->clk_src; + } + size_t mem_block_symbols = LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS; + // override the default value if the user sets it + if (rmt_config->mem_block_symbols) { + mem_block_symbols = rmt_config->mem_block_symbols; + } + rmt_tx_channel_config_t rmt_chan_config = { + .clk_src = clk_src, + .gpio_num = led_config->strip_gpio_num, + .mem_block_symbols = mem_block_symbols, + .resolution_hz = resolution, + .trans_queue_depth = LED_STRIP_RMT_DEFAULT_TRANS_QUEUE_SIZE, + .flags.with_dma = rmt_config->flags.with_dma, + .flags.invert_out = led_config->flags.invert_out, + }; + ESP_GOTO_ON_ERROR(rmt_new_tx_channel(&rmt_chan_config, &rmt_strip->rmt_chan), err, TAG, "create RMT TX channel failed"); + + led_strip_encoder_config_t strip_encoder_conf = { + .resolution = resolution, + .led_model = led_config->led_model + }; + ESP_GOTO_ON_ERROR(rmt_new_led_strip_encoder(&strip_encoder_conf, &rmt_strip->strip_encoder), err, TAG, "create LED strip encoder failed"); + + + rmt_strip->bytes_per_pixel = bytes_per_pixel; + rmt_strip->strip_len = led_config->max_leds; + rmt_strip->base.set_pixel = led_strip_rmt_set_pixel; + rmt_strip->base.set_pixel_rgbw = led_strip_rmt_set_pixel_rgbw; + rmt_strip->base.refresh = led_strip_rmt_refresh; + rmt_strip->base.clear = led_strip_rmt_clear; + rmt_strip->base.del = led_strip_rmt_del; + + *ret_strip = &rmt_strip->base; + return ESP_OK; +err: + if (rmt_strip) { + if (rmt_strip->rmt_chan) { + rmt_del_channel(rmt_strip->rmt_chan); + } + if (rmt_strip->strip_encoder) { + rmt_del_encoder(rmt_strip->strip_encoder); + } + free(rmt_strip); + } + return ret; +} diff --git a/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_dev_idf4.c b/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_dev_idf4.c new file mode 100644 index 000000000..a1067cd7c --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_dev_idf4.c @@ -0,0 +1,194 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include "esp_log.h" +#include "esp_check.h" +#include "driver/rmt.h" +#include "led_strip.h" +#include "led_strip_interface.h" + +static const char *TAG = "led_strip_rmt"; + +#define WS2812_T0H_NS (300) +#define WS2812_T0L_NS (900) +#define WS2812_T1H_NS (900) +#define WS2812_T1L_NS (300) + +#define SK6812_T0H_NS (300) +#define SK6812_T0L_NS (900) +#define SK6812_T1H_NS (600) +#define SK6812_T1L_NS (600) + +#define LED_STRIP_RESET_MS (10) + +// the memory size of each RMT channel, in words (4 bytes) +#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 +#define LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS 64 +#else +#define LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS 48 +#endif + +static uint32_t led_t0h_ticks = 0; +static uint32_t led_t1h_ticks = 0; +static uint32_t led_t0l_ticks = 0; +static uint32_t led_t1l_ticks = 0; + +typedef struct { + led_strip_t base; + rmt_channel_t rmt_channel; + uint32_t strip_len; + uint8_t bytes_per_pixel; + uint8_t buffer[0]; +} led_strip_rmt_obj; + +static void IRAM_ATTR ws2812_rmt_adapter(const void *src, rmt_item32_t *dest, size_t src_size, + size_t wanted_num, size_t *translated_size, size_t *item_num) +{ + if (src == NULL || dest == NULL) { + *translated_size = 0; + *item_num = 0; + return; + } + const rmt_item32_t bit0 = {{{ led_t0h_ticks, 1, led_t0l_ticks, 0 }}}; //Logical 0 + const rmt_item32_t bit1 = {{{ led_t1h_ticks, 1, led_t1l_ticks, 0 }}}; //Logical 1 + size_t size = 0; + size_t num = 0; + uint8_t *psrc = (uint8_t *)src; + rmt_item32_t *pdest = dest; + while (size < src_size && num < wanted_num) { + for (int i = 0; i < 8; i++) { + // MSB first + if (*psrc & (1 << (7 - i))) { + pdest->val = bit1.val; + } else { + pdest->val = bit0.val; + } + num++; + pdest++; + } + size++; + psrc++; + } + *translated_size = size; + *item_num = num; +} + +static esp_err_t led_strip_rmt_set_pixel(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue) +{ + led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); + ESP_RETURN_ON_FALSE(index < rmt_strip->strip_len, ESP_ERR_INVALID_ARG, TAG, "index out of the maximum number of leds"); + uint32_t start = index * rmt_strip->bytes_per_pixel; + // In thr order of GRB + rmt_strip->buffer[start + 0] = green & 0xFF; + rmt_strip->buffer[start + 1] = red & 0xFF; + rmt_strip->buffer[start + 2] = blue & 0xFF; + if (rmt_strip->bytes_per_pixel > 3) { + rmt_strip->buffer[start + 3] = 0; + } + return ESP_OK; +} + +static esp_err_t led_strip_rmt_refresh(led_strip_t *strip) +{ + led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); + ESP_RETURN_ON_ERROR(rmt_write_sample(rmt_strip->rmt_channel, rmt_strip->buffer, rmt_strip->strip_len * rmt_strip->bytes_per_pixel, true), TAG, + "transmit RMT samples failed"); + vTaskDelay(pdMS_TO_TICKS(LED_STRIP_RESET_MS)); + return ESP_OK; +} + +static esp_err_t led_strip_rmt_clear(led_strip_t *strip) +{ + led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); + // Write zero to turn off all LEDs + memset(rmt_strip->buffer, 0, rmt_strip->strip_len * rmt_strip->bytes_per_pixel); + return led_strip_rmt_refresh(strip); +} + +static esp_err_t led_strip_rmt_del(led_strip_t *strip) +{ + led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); + ESP_RETURN_ON_ERROR(rmt_driver_uninstall(rmt_strip->rmt_channel), TAG, "uninstall RMT driver failed"); + free(rmt_strip); + return ESP_OK; +} + +esp_err_t led_strip_new_rmt_device(const led_strip_config_t *led_config, const led_strip_rmt_config_t *dev_config, led_strip_handle_t *ret_strip) +{ + led_strip_rmt_obj *rmt_strip = NULL; + esp_err_t ret = ESP_OK; + ESP_RETURN_ON_FALSE(led_config && dev_config && ret_strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + ESP_RETURN_ON_FALSE(led_config->led_pixel_format < LED_PIXEL_FORMAT_INVALID, ESP_ERR_INVALID_ARG, TAG, "invalid led_pixel_format"); + ESP_RETURN_ON_FALSE(dev_config->flags.with_dma == 0, ESP_ERR_NOT_SUPPORTED, TAG, "DMA is not supported"); + + uint8_t bytes_per_pixel = 3; + if (led_config->led_pixel_format == LED_PIXEL_FORMAT_GRBW) { + bytes_per_pixel = 4; + } else if (led_config->led_pixel_format == LED_PIXEL_FORMAT_GRB) { + bytes_per_pixel = 3; + } else { + assert(false); + } + + // allocate memory for led_strip object + rmt_strip = calloc(1, sizeof(led_strip_rmt_obj) + led_config->max_leds * bytes_per_pixel); + ESP_RETURN_ON_FALSE(rmt_strip, ESP_ERR_NO_MEM, TAG, "request memory for les_strip failed"); + + // install RMT channel driver + rmt_config_t config = RMT_DEFAULT_CONFIG_TX(led_config->strip_gpio_num, dev_config->rmt_channel); + // set the minimal clock division because the LED strip needs a high clock resolution + config.clk_div = 2; + + uint8_t mem_block_num = 2; + // override the default value if the user specify the mem block size + if (dev_config->mem_block_symbols) { + mem_block_num = (dev_config->mem_block_symbols + LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS / 2) / LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS; + } + config.mem_block_num = mem_block_num; + + ESP_GOTO_ON_ERROR(rmt_config(&config), err, TAG, "RMT config failed"); + ESP_GOTO_ON_ERROR(rmt_driver_install(config.channel, 0, 0), err, TAG, "RMT install failed"); + + uint32_t counter_clk_hz = 0; + rmt_get_counter_clock((rmt_channel_t)dev_config->rmt_channel, &counter_clk_hz); + // ns -> ticks + float ratio = (float)counter_clk_hz / 1e9; + if (led_config->led_model == LED_MODEL_WS2812) { + led_t0h_ticks = (uint32_t)(ratio * WS2812_T0H_NS); + led_t0l_ticks = (uint32_t)(ratio * WS2812_T0L_NS); + led_t1h_ticks = (uint32_t)(ratio * WS2812_T1H_NS); + led_t1l_ticks = (uint32_t)(ratio * WS2812_T1L_NS); + } else if (led_config->led_model == LED_MODEL_SK6812) { + led_t0h_ticks = (uint32_t)(ratio * SK6812_T0H_NS); + led_t0l_ticks = (uint32_t)(ratio * SK6812_T0L_NS); + led_t1h_ticks = (uint32_t)(ratio * SK6812_T1H_NS); + led_t1l_ticks = (uint32_t)(ratio * SK6812_T1L_NS); + } else { + assert(false); + } + + // adapter to translates the LES strip date frame into RMT symbols + rmt_translator_init((rmt_channel_t)dev_config->rmt_channel, ws2812_rmt_adapter); + + rmt_strip->bytes_per_pixel = bytes_per_pixel; + rmt_strip->rmt_channel = (rmt_channel_t)dev_config->rmt_channel; + rmt_strip->strip_len = led_config->max_leds; + rmt_strip->base.set_pixel = led_strip_rmt_set_pixel; + rmt_strip->base.refresh = led_strip_rmt_refresh; + rmt_strip->base.clear = led_strip_rmt_clear; + rmt_strip->base.del = led_strip_rmt_del; + + *ret_strip = &rmt_strip->base; + return ESP_OK; + +err: + if (rmt_strip) { + free(rmt_strip); + } + return ret; +} diff --git a/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_encoder.c b/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_encoder.c new file mode 100644 index 000000000..d352ac07f --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_encoder.c @@ -0,0 +1,146 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_check.h" +#include "led_strip_rmt_encoder.h" + +static const char *TAG = "led_rmt_encoder"; + +typedef struct { + rmt_encoder_t base; + rmt_encoder_t *bytes_encoder; + rmt_encoder_t *copy_encoder; + int state; + rmt_symbol_word_t reset_code; +} rmt_led_strip_encoder_t; + +static size_t rmt_encode_led_strip(rmt_encoder_t *encoder, rmt_channel_handle_t channel, const void *primary_data, size_t data_size, rmt_encode_state_t *ret_state) +{ + rmt_led_strip_encoder_t *led_encoder = __containerof(encoder, rmt_led_strip_encoder_t, base); + rmt_encoder_handle_t bytes_encoder = led_encoder->bytes_encoder; + rmt_encoder_handle_t copy_encoder = led_encoder->copy_encoder; + rmt_encode_state_t session_state = 0; + rmt_encode_state_t state = 0; + size_t encoded_symbols = 0; + switch (led_encoder->state) { + case 0: // send RGB data + encoded_symbols += bytes_encoder->encode(bytes_encoder, channel, primary_data, data_size, &session_state); + if (session_state & RMT_ENCODING_COMPLETE) { + led_encoder->state = 1; // switch to next state when current encoding session finished + } + if (session_state & RMT_ENCODING_MEM_FULL) { + state |= RMT_ENCODING_MEM_FULL; + goto out; // yield if there's no free space for encoding artifacts + } + // fall-through + case 1: // send reset code + encoded_symbols += copy_encoder->encode(copy_encoder, channel, &led_encoder->reset_code, + sizeof(led_encoder->reset_code), &session_state); + if (session_state & RMT_ENCODING_COMPLETE) { + led_encoder->state = 0; // back to the initial encoding session + state |= RMT_ENCODING_COMPLETE; + } + if (session_state & RMT_ENCODING_MEM_FULL) { + state |= RMT_ENCODING_MEM_FULL; + goto out; // yield if there's no free space for encoding artifacts + } + } +out: + *ret_state = state; + return encoded_symbols; +} + +static esp_err_t rmt_del_led_strip_encoder(rmt_encoder_t *encoder) +{ + rmt_led_strip_encoder_t *led_encoder = __containerof(encoder, rmt_led_strip_encoder_t, base); + rmt_del_encoder(led_encoder->bytes_encoder); + rmt_del_encoder(led_encoder->copy_encoder); + free(led_encoder); + return ESP_OK; +} + +static esp_err_t rmt_led_strip_encoder_reset(rmt_encoder_t *encoder) +{ + rmt_led_strip_encoder_t *led_encoder = __containerof(encoder, rmt_led_strip_encoder_t, base); + rmt_encoder_reset(led_encoder->bytes_encoder); + rmt_encoder_reset(led_encoder->copy_encoder); + led_encoder->state = 0; + return ESP_OK; +} + +esp_err_t rmt_new_led_strip_encoder(const led_strip_encoder_config_t *config, rmt_encoder_handle_t *ret_encoder) +{ + esp_err_t ret = ESP_OK; + rmt_led_strip_encoder_t *led_encoder = NULL; + ESP_GOTO_ON_FALSE(config && ret_encoder, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); + ESP_GOTO_ON_FALSE(config->led_model < LED_MODEL_INVALID, ESP_ERR_INVALID_ARG, err, TAG, "invalid led model"); + led_encoder = calloc(1, sizeof(rmt_led_strip_encoder_t)); + ESP_GOTO_ON_FALSE(led_encoder, ESP_ERR_NO_MEM, err, TAG, "no mem for led strip encoder"); + led_encoder->base.encode = rmt_encode_led_strip; + led_encoder->base.del = rmt_del_led_strip_encoder; + led_encoder->base.reset = rmt_led_strip_encoder_reset; + rmt_bytes_encoder_config_t bytes_encoder_config; + if (config->led_model == LED_MODEL_SK6812) { + bytes_encoder_config = (rmt_bytes_encoder_config_t) { + .bit0 = { + .level0 = 1, + .duration0 = 0.3 * config->resolution / 1000000, // T0H=0.3us + .level1 = 0, + .duration1 = 0.9 * config->resolution / 1000000, // T0L=0.9us + }, + .bit1 = { + .level0 = 1, + .duration0 = 0.6 * config->resolution / 1000000, // T1H=0.6us + .level1 = 0, + .duration1 = 0.6 * config->resolution / 1000000, // T1L=0.6us + }, + .flags.msb_first = 1 // SK6812 transfer bit order: G7...G0R7...R0B7...B0(W7...W0) + }; + } else if (config->led_model == LED_MODEL_WS2812) { + // different led strip might have its own timing requirements, following parameter is for WS2812 + bytes_encoder_config = (rmt_bytes_encoder_config_t) { + .bit0 = { + .level0 = 1, + .duration0 = 0.3 * config->resolution / 1000000, // T0H=0.3us + .level1 = 0, + .duration1 = 0.9 * config->resolution / 1000000, // T0L=0.9us + }, + .bit1 = { + .level0 = 1, + .duration0 = 0.9 * config->resolution / 1000000, // T1H=0.9us + .level1 = 0, + .duration1 = 0.3 * config->resolution / 1000000, // T1L=0.3us + }, + .flags.msb_first = 1 // WS2812 transfer bit order: G7...G0R7...R0B7...B0 + }; + } else { + assert(false); + } + ESP_GOTO_ON_ERROR(rmt_new_bytes_encoder(&bytes_encoder_config, &led_encoder->bytes_encoder), err, TAG, "create bytes encoder failed"); + rmt_copy_encoder_config_t copy_encoder_config = {}; + ESP_GOTO_ON_ERROR(rmt_new_copy_encoder(©_encoder_config, &led_encoder->copy_encoder), err, TAG, "create copy encoder failed"); + + uint32_t reset_ticks = config->resolution / 1000000 * 50 / 2; // reset code duration defaults to 50us + led_encoder->reset_code = (rmt_symbol_word_t) { + .level0 = 0, + .duration0 = reset_ticks, + .level1 = 0, + .duration1 = reset_ticks, + }; + *ret_encoder = &led_encoder->base; + return ESP_OK; +err: + if (led_encoder) { + if (led_encoder->bytes_encoder) { + rmt_del_encoder(led_encoder->bytes_encoder); + } + if (led_encoder->copy_encoder) { + rmt_del_encoder(led_encoder->copy_encoder); + } + free(led_encoder); + } + return ret; +} diff --git a/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_encoder.h b/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_encoder.h new file mode 100644 index 000000000..ba71e60ab --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_encoder.h @@ -0,0 +1,38 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include "driver/rmt_encoder.h" +#include "led_strip_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Type of led strip encoder configuration + */ +typedef struct { + uint32_t resolution; /*!< Encoder resolution, in Hz */ + led_model_t led_model; /*!< LED model */ +} led_strip_encoder_config_t; + +/** + * @brief Create RMT encoder for encoding LED strip pixels into RMT symbols + * + * @param[in] config Encoder configuration + * @param[out] ret_encoder Returned encoder handle + * @return + * - ESP_ERR_INVALID_ARG for any invalid arguments + * - ESP_ERR_NO_MEM out of memory when creating led strip encoder + * - ESP_OK if creating encoder successfully + */ +esp_err_t rmt_new_led_strip_encoder(const led_strip_encoder_config_t *config, rmt_encoder_handle_t *ret_encoder); + +#ifdef __cplusplus +} +#endif diff --git a/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_ws2812.c b/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_ws2812.c deleted file mode 100644 index fd1746cad..000000000 --- a/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_ws2812.c +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright 2019 Espressif Systems (Shanghai) PTE LTD -// -// 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. -#include -#include -#include -#include "esp_log.h" -#include "esp_attr.h" -#include "led_strip.h" -#include "driver/rmt.h" - -static const char *TAG = "ws2812"; -#define STRIP_CHECK(a, str, goto_tag, ret_value, ...) \ - do \ - { \ - if (!(a)) \ - { \ - ESP_LOGE(TAG, "%s(%d): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ - ret = ret_value; \ - goto goto_tag; \ - } \ - } while (0) - -#define WS2812_T0H_NS (350) -#define WS2812_T0L_NS (1000) -#define WS2812_T1H_NS (1000) -#define WS2812_T1L_NS (350) -#define WS2812_RESET_US (280) - -static uint32_t ws2812_t0h_ticks = 0; -static uint32_t ws2812_t1h_ticks = 0; -static uint32_t ws2812_t0l_ticks = 0; -static uint32_t ws2812_t1l_ticks = 0; - -typedef struct { - led_strip_t parent; - rmt_channel_t rmt_channel; - uint32_t strip_len; - uint8_t buffer[0]; -} ws2812_t; - -/** - * @brief Convert RGB data to RMT format. - * - * @note For WS2812, R,G,B each contains 256 different choices (i.e. uint8_t) - * - * @param[in] src: source data, to converted to RMT format - * @param[in] dest: place where to store the convert result - * @param[in] src_size: size of source data - * @param[in] wanted_num: number of RMT items that want to get - * @param[out] translated_size: number of source data that got converted - * @param[out] item_num: number of RMT items which are converted from source data - */ -static void IRAM_ATTR ws2812_rmt_adapter(const void *src, rmt_item32_t *dest, size_t src_size, - size_t wanted_num, size_t *translated_size, size_t *item_num) -{ - if (src == NULL || dest == NULL) { - *translated_size = 0; - *item_num = 0; - return; - } - const rmt_item32_t bit0 = {{{ ws2812_t0h_ticks, 1, ws2812_t0l_ticks, 0 }}}; //Logical 0 - const rmt_item32_t bit1 = {{{ ws2812_t1h_ticks, 1, ws2812_t1l_ticks, 0 }}}; //Logical 1 - size_t size = 0; - size_t num = 0; - uint8_t *psrc = (uint8_t *)src; - rmt_item32_t *pdest = dest; - while (size < src_size && num < wanted_num) { - for (int i = 0; i < 8; i++) { - // MSB first - if (*psrc & (1 << (7 - i))) { - pdest->val = bit1.val; - } else { - pdest->val = bit0.val; - } - num++; - pdest++; - } - size++; - psrc++; - } - *translated_size = size; - *item_num = num; -} - -static esp_err_t ws2812_set_pixel(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue) -{ - esp_err_t ret = ESP_OK; - ws2812_t *ws2812 = __containerof(strip, ws2812_t, parent); - STRIP_CHECK(index < ws2812->strip_len, "index out of the maximum number of leds", err, ESP_ERR_INVALID_ARG); - uint32_t start = index * 3; - // In thr order of GRB - ws2812->buffer[start + 0] = green & 0xFF; - ws2812->buffer[start + 1] = red & 0xFF; - ws2812->buffer[start + 2] = blue & 0xFF; - return ESP_OK; -err: - return ret; -} - -static esp_err_t ws2812_refresh(led_strip_t *strip, uint32_t timeout_ms) -{ - esp_err_t ret = ESP_OK; - ws2812_t *ws2812 = __containerof(strip, ws2812_t, parent); - STRIP_CHECK(rmt_write_sample(ws2812->rmt_channel, ws2812->buffer, ws2812->strip_len * 3, true) == ESP_OK, - "transmit RMT samples failed", err, ESP_FAIL); - return rmt_wait_tx_done(ws2812->rmt_channel, pdMS_TO_TICKS(timeout_ms)); -err: - return ret; -} - -static esp_err_t ws2812_clear(led_strip_t *strip, uint32_t timeout_ms) -{ - ws2812_t *ws2812 = __containerof(strip, ws2812_t, parent); - // Write zero to turn off all leds - memset(ws2812->buffer, 0, ws2812->strip_len * 3); - return ws2812_refresh(strip, timeout_ms); -} - -static esp_err_t ws2812_del(led_strip_t *strip) -{ - ws2812_t *ws2812 = __containerof(strip, ws2812_t, parent); - free(ws2812); - return ESP_OK; -} - -led_strip_t *led_strip_new_rmt_ws2812(const led_strip_config_t *config) -{ - led_strip_t *ret = NULL; - STRIP_CHECK(config, "configuration can't be null", err, NULL); - - // 24 bits per led - uint32_t ws2812_size = sizeof(ws2812_t) + config->max_leds * 3; - ws2812_t *ws2812 = calloc(1, ws2812_size); - STRIP_CHECK(ws2812, "request memory for ws2812 failed", err, NULL); - - uint32_t counter_clk_hz = 0; - STRIP_CHECK(rmt_get_counter_clock((rmt_channel_t)config->dev, &counter_clk_hz) == ESP_OK, - "get rmt counter clock failed", err, NULL); - // ns -> ticks - float ratio = (float)counter_clk_hz / 1e9; - ws2812_t0h_ticks = (uint32_t)(ratio * WS2812_T0H_NS); - ws2812_t0l_ticks = (uint32_t)(ratio * WS2812_T0L_NS); - ws2812_t1h_ticks = (uint32_t)(ratio * WS2812_T1H_NS); - ws2812_t1l_ticks = (uint32_t)(ratio * WS2812_T1L_NS); - - // set ws2812 to rmt adapter - rmt_translator_init((rmt_channel_t)config->dev, ws2812_rmt_adapter); - - ws2812->rmt_channel = (rmt_channel_t)config->dev; - ws2812->strip_len = config->max_leds; - - ws2812->parent.set_pixel = ws2812_set_pixel; - ws2812->parent.refresh = ws2812_refresh; - ws2812->parent.clear = ws2812_clear; - ws2812->parent.del = ws2812_del; - - return &ws2812->parent; -err: - return ret; -} diff --git a/hw/bsp/espressif/components/led_strip/src/led_strip_spi_dev.c b/hw/bsp/espressif/components/led_strip/src/led_strip_spi_dev.c new file mode 100644 index 000000000..12ea8fbf3 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/src/led_strip_spi_dev.c @@ -0,0 +1,209 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include "esp_log.h" +#include "esp_check.h" +#include "esp_rom_gpio.h" +#include "soc/spi_periph.h" +#include "led_strip.h" +#include "led_strip_interface.h" +#include "hal/spi_hal.h" + +#define LED_STRIP_SPI_DEFAULT_RESOLUTION (2.5 * 1000 * 1000) // 2.5MHz resolution +#define LED_STRIP_SPI_DEFAULT_TRANS_QUEUE_SIZE 4 + +#define SPI_BYTES_PER_COLOR_BYTE 3 +#define SPI_BITS_PER_COLOR_BYTE (SPI_BYTES_PER_COLOR_BYTE * 8) + +static const char *TAG = "led_strip_spi"; + +typedef struct { + led_strip_t base; + spi_host_device_t spi_host; + spi_device_handle_t spi_device; + uint32_t strip_len; + uint8_t bytes_per_pixel; + uint8_t pixel_buf[]; +} led_strip_spi_obj; + +// please make sure to zero-initialize the buf before calling this function +static void __led_strip_spi_bit(uint8_t data, uint8_t *buf) +{ + // Each color of 1 bit is represented by 3 bits of SPI, low_level:100 ,high_level:110 + // So a color byte occupies 3 bytes of SPI. + *(buf + 2) |= data & BIT(0) ? BIT(2) | BIT(1) : BIT(2); + *(buf + 2) |= data & BIT(1) ? BIT(5) | BIT(4) : BIT(5); + *(buf + 2) |= data & BIT(2) ? BIT(7) : 0x00; + *(buf + 1) |= BIT(0); + *(buf + 1) |= data & BIT(3) ? BIT(3) | BIT(2) : BIT(3); + *(buf + 1) |= data & BIT(4) ? BIT(6) | BIT(5) : BIT(6); + *(buf + 0) |= data & BIT(5) ? BIT(1) | BIT(0) : BIT(1); + *(buf + 0) |= data & BIT(6) ? BIT(4) | BIT(3) : BIT(4); + *(buf + 0) |= data & BIT(7) ? BIT(7) | BIT(6) : BIT(7); +} + +static esp_err_t led_strip_spi_set_pixel(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue) +{ + led_strip_spi_obj *spi_strip = __containerof(strip, led_strip_spi_obj, base); + ESP_RETURN_ON_FALSE(index < spi_strip->strip_len, ESP_ERR_INVALID_ARG, TAG, "index out of maximum number of LEDs"); + // LED_PIXEL_FORMAT_GRB takes 72bits(9bytes) + uint32_t start = index * spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE; + memset(spi_strip->pixel_buf + start, 0, spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE); + __led_strip_spi_bit(green, &spi_strip->pixel_buf[start]); + __led_strip_spi_bit(red, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE]); + __led_strip_spi_bit(blue, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * 2]); + if (spi_strip->bytes_per_pixel > 3) { + __led_strip_spi_bit(0, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * 3]); + } + return ESP_OK; +} + +static esp_err_t led_strip_spi_set_pixel_rgbw(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue, uint32_t white) +{ + led_strip_spi_obj *spi_strip = __containerof(strip, led_strip_spi_obj, base); + ESP_RETURN_ON_FALSE(index < spi_strip->strip_len, ESP_ERR_INVALID_ARG, TAG, "index out of maximum number of LEDs"); + ESP_RETURN_ON_FALSE(spi_strip->bytes_per_pixel == 4, ESP_ERR_INVALID_ARG, TAG, "wrong LED pixel format, expected 4 bytes per pixel"); + // LED_PIXEL_FORMAT_GRBW takes 96bits(12bytes) + uint32_t start = index * spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE; + // SK6812 component order is GRBW + memset(spi_strip->pixel_buf + start, 0, spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE); + __led_strip_spi_bit(green, &spi_strip->pixel_buf[start]); + __led_strip_spi_bit(red, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE]); + __led_strip_spi_bit(blue, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * 2]); + __led_strip_spi_bit(white, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * 3]); + + return ESP_OK; +} + +static esp_err_t led_strip_spi_refresh(led_strip_t *strip) +{ + led_strip_spi_obj *spi_strip = __containerof(strip, led_strip_spi_obj, base); + spi_transaction_t tx_conf; + memset(&tx_conf, 0, sizeof(tx_conf)); + + tx_conf.length = spi_strip->strip_len * spi_strip->bytes_per_pixel * SPI_BITS_PER_COLOR_BYTE; + tx_conf.tx_buffer = spi_strip->pixel_buf; + tx_conf.rx_buffer = NULL; + ESP_RETURN_ON_ERROR(spi_device_transmit(spi_strip->spi_device, &tx_conf), TAG, "transmit pixels by SPI failed"); + + return ESP_OK; +} + +static esp_err_t led_strip_spi_clear(led_strip_t *strip) +{ + led_strip_spi_obj *spi_strip = __containerof(strip, led_strip_spi_obj, base); + //Write zero to turn off all leds + memset(spi_strip->pixel_buf, 0, spi_strip->strip_len * spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE); + uint8_t *buf = spi_strip->pixel_buf; + for (int index = 0; index < spi_strip->strip_len * spi_strip->bytes_per_pixel; index++) { + __led_strip_spi_bit(0, buf); + buf += SPI_BYTES_PER_COLOR_BYTE; + } + + return led_strip_spi_refresh(strip); +} + +static esp_err_t led_strip_spi_del(led_strip_t *strip) +{ + led_strip_spi_obj *spi_strip = __containerof(strip, led_strip_spi_obj, base); + + ESP_RETURN_ON_ERROR(spi_bus_remove_device(spi_strip->spi_device), TAG, "delete spi device failed"); + ESP_RETURN_ON_ERROR(spi_bus_free(spi_strip->spi_host), TAG, "free spi bus failed"); + + free(spi_strip); + return ESP_OK; +} + +esp_err_t led_strip_new_spi_device(const led_strip_config_t *led_config, const led_strip_spi_config_t *spi_config, led_strip_handle_t *ret_strip) +{ + led_strip_spi_obj *spi_strip = NULL; + esp_err_t ret = ESP_OK; + ESP_GOTO_ON_FALSE(led_config && spi_config && ret_strip, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); + ESP_GOTO_ON_FALSE(led_config->led_pixel_format < LED_PIXEL_FORMAT_INVALID, ESP_ERR_INVALID_ARG, err, TAG, "invalid led_pixel_format"); + uint8_t bytes_per_pixel = 3; + if (led_config->led_pixel_format == LED_PIXEL_FORMAT_GRBW) { + bytes_per_pixel = 4; + } else if (led_config->led_pixel_format == LED_PIXEL_FORMAT_GRB) { + bytes_per_pixel = 3; + } else { + assert(false); + } + uint32_t mem_caps = MALLOC_CAP_DEFAULT; + if (spi_config->flags.with_dma) { + // DMA buffer must be placed in internal SRAM + mem_caps |= MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA; + } + spi_strip = heap_caps_calloc(1, sizeof(led_strip_spi_obj) + led_config->max_leds * bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE, mem_caps); + + ESP_GOTO_ON_FALSE(spi_strip, ESP_ERR_NO_MEM, err, TAG, "no mem for spi strip"); + + spi_strip->spi_host = spi_config->spi_bus; + // for backward compatibility, if the user does not set the clk_src, use the default value + spi_clock_source_t clk_src = SPI_CLK_SRC_DEFAULT; + if (spi_config->clk_src) { + clk_src = spi_config->clk_src; + } + + spi_bus_config_t spi_bus_cfg = { + .mosi_io_num = led_config->strip_gpio_num, + //Only use MOSI to generate the signal, set -1 when other pins are not used. + .miso_io_num = -1, + .sclk_io_num = -1, + .quadwp_io_num = -1, + .quadhd_io_num = -1, + .max_transfer_sz = led_config->max_leds * bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE, + }; + ESP_GOTO_ON_ERROR(spi_bus_initialize(spi_strip->spi_host, &spi_bus_cfg, spi_config->flags.with_dma ? SPI_DMA_CH_AUTO : SPI_DMA_DISABLED), err, TAG, "create SPI bus failed"); + + if (led_config->flags.invert_out == true) { + esp_rom_gpio_connect_out_signal(led_config->strip_gpio_num, spi_periph_signal[spi_strip->spi_host].spid_out, true, false); + } + + spi_device_interface_config_t spi_dev_cfg = { + .clock_source = clk_src, + .command_bits = 0, + .address_bits = 0, + .dummy_bits = 0, + .clock_speed_hz = LED_STRIP_SPI_DEFAULT_RESOLUTION, + .mode = 0, + //set -1 when CS is not used + .spics_io_num = -1, + .queue_size = LED_STRIP_SPI_DEFAULT_TRANS_QUEUE_SIZE, + }; + + ESP_GOTO_ON_ERROR(spi_bus_add_device(spi_strip->spi_host, &spi_dev_cfg, &spi_strip->spi_device), err, TAG, "Failed to add spi device"); + + int clock_resolution_khz = 0; + spi_device_get_actual_freq(spi_strip->spi_device, &clock_resolution_khz); + // TODO: ideally we should decide the SPI_BYTES_PER_COLOR_BYTE by the real clock resolution + // But now, let's fixed the resolution, the downside is, we don't support a clock source whose frequency is not multiple of LED_STRIP_SPI_DEFAULT_RESOLUTION + ESP_GOTO_ON_FALSE(clock_resolution_khz == LED_STRIP_SPI_DEFAULT_RESOLUTION / 1000, ESP_ERR_NOT_SUPPORTED, err, + TAG, "unsupported clock resolution:%dKHz", clock_resolution_khz); + + spi_strip->bytes_per_pixel = bytes_per_pixel; + spi_strip->strip_len = led_config->max_leds; + spi_strip->base.set_pixel = led_strip_spi_set_pixel; + spi_strip->base.set_pixel_rgbw = led_strip_spi_set_pixel_rgbw; + spi_strip->base.refresh = led_strip_spi_refresh; + spi_strip->base.clear = led_strip_spi_clear; + spi_strip->base.del = led_strip_spi_del; + + *ret_strip = &spi_strip->base; + return ESP_OK; +err: + if (spi_strip) { + if (spi_strip->spi_device) { + spi_bus_remove_device(spi_strip->spi_device); + } + if (spi_strip->spi_host) { + spi_bus_free(spi_strip->spi_host); + } + free(spi_strip); + } + return ret; +} diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index 539a776a6..ff3393cfd 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -211,7 +211,6 @@ function(family_configure_common TARGET RTOS) target_link_options(${TARGET} PUBLIC "LINKER:--map=$.map") endif() - # ETM Trace option if (TRACE_ETM STREQUAL "1") target_compile_definitions(${TARGET} PUBLIC TRACE_ETM) diff --git a/hw/bsp/mcx/boards/bunny-brain/board.cmake b/hw/bsp/mcx/boards/bunny-brain/board.cmake deleted file mode 100644 index 8c3280743..000000000 --- a/hw/bsp/mcx/boards/bunny-brain/board.cmake +++ /dev/null @@ -1,21 +0,0 @@ -set(MCU_VARIANT MCXN947) -set(MCU_CORE MCXN947_cm33_core0) - -set(JLINK_DEVICE MCXN947_M33_0) -set(PYOCD_TARGET MCXN947) -set(NXPLINK_DEVICE MCXN947:MCXN947) - -set(PORT 1) - -function(update_board TARGET) - target_compile_definitions(${TARGET} PUBLIC - CPU_MCXN947VDF_cm33_core0 - BOARD_TUD_RHPORT=${PORT} - # port 0 is fullspeed, port 1 is highspeed - BOARD_TUD_MAX_SPEED=$ - ) - target_sources(${TARGET} PUBLIC - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/clock_config.c - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/pin_mux.c - ) -endfunction() diff --git a/hw/bsp/mcx/boards/bunny-brain/board.h b/hw/bsp/mcx/boards/bunny-brain/board.h deleted file mode 100644 index eae98bfa7..000000000 --- a/hw/bsp/mcx/boards/bunny-brain/board.h +++ /dev/null @@ -1,66 +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 - -// LED -#define LED_GPIO GPIO3 -#define LED_CLK kCLOCK_Gpio3 -#define LED_PIN 4 // red -#define LED_STATE_ON 0 - -// WAKE button (Dummy, use unused pin -#define BUTTON_GPIO GPIO0 -#define BUTTON_CLK kCLOCK_Gpio0 -#define BUTTON_PIN 6 -#define BUTTON_STATE_ACTIVE 0 - -// UART -#define UART_DEV LPUART4 - -static inline void board_uart_init_clock(void) { - /* attach FRO 12M to FLEXCOMM4 */ - CLOCK_SetClkDiv(kCLOCK_DivFlexcom4Clk, 1u); - CLOCK_AttachClk(kFRO12M_to_FLEXCOMM4); - RESET_ClearPeripheralReset(kFC4_RST_SHIFT_RSTn); -} - -//#define UART_RX_PINMUX 0, 24, IOCON_PIO_DIG_FUNC1_EN -//#define UART_TX_PINMUX 0, 25, IOCON_PIO_DIG_FUNC1_EN - -// XTAL -#define XTAL0_CLK_HZ (24 * 1000 * 1000U) - -#ifdef __cplusplus - } -#endif - -#endif diff --git a/hw/bsp/mcx/boards/bunny-brain/board.mk b/hw/bsp/mcx/boards/bunny-brain/board.mk deleted file mode 100644 index aaad5e73e..000000000 --- a/hw/bsp/mcx/boards/bunny-brain/board.mk +++ /dev/null @@ -1,11 +0,0 @@ -MCU_VARIANT = MCXN947 -MCU_CORE = MCXN947_cm33_core0 -PORT ?= 1 - -CFLAGS += -DCPU_MCXN947VDF_cm33_core0 - -JLINK_DEVICE = MCXN947_M33_0 -PYOCD_TARGET = MCXN947 - -# flash using pyocd -flash: flash-jlink diff --git a/hw/bsp/mcx/boards/bunny-brain/clock_config.c b/hw/bsp/mcx/boards/bunny-brain/clock_config.c deleted file mode 100644 index 37d2b4dfc..000000000 --- a/hw/bsp/mcx/boards/bunny-brain/clock_config.c +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Copyright 2022 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/*********************************************************************************************************************** - * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file - * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. - **********************************************************************************************************************/ -/* - * How to setup clock using clock driver functions: - * - * 1. Setup clock sources. - * - * 2. Set up wait states of the flash. - * - * 3. Set up all dividers. - * - * 4. Set up all selectors to provide selected clocks. - * - */ - -/* clang-format off */ -/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* -!!GlobalInfo -product: Clocks v10.0 -processor: MCXN947 -package_id: MCXN947VDF -mcu_data: ksdk2_0 -processor_version: 0.12.3 -board: MCX-N9XX-EVK - * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ -/* clang-format on */ - -#include "clock_config.h" -#include "fsl_clock.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/******************************************************************************* - * Variables - ******************************************************************************/ -/* System clock frequency. */ -// extern uint32_t SystemCoreClock; - -/******************************************************************************* - ************************ BOARD_InitBootClocks function ************************ - ******************************************************************************/ -void BOARD_InitBootClocks(void) -{ - BOARD_BootClockPLL150M(); -} - -/******************************************************************************* - ******************** Configuration BOARD_BootClockFRO12M ********************** - ******************************************************************************/ -/* clang-format off */ -/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* -!!Configuration -name: BOARD_BootClockFRO12M -outputs: -- {id: CLK_144M_clock.outFreq, value: 144 MHz} -- {id: CLK_48M_clock.outFreq, value: 48 MHz} -- {id: FRO_12M_clock.outFreq, value: 12 MHz} -- {id: MAIN_clock.outFreq, value: 12 MHz} -- {id: Slow_clock.outFreq, value: 3 MHz} -- {id: System_clock.outFreq, value: 12 MHz} -- {id: gdet_clock.outFreq, value: 48 MHz} -- {id: trng_clock.outFreq, value: 48 MHz} -settings: -- {id: SCGMode, value: SIRC} -- {id: SCG.SCSSEL.sel, value: SCG.SIRC} -- {id: SCG_FIRCCSR_FIRCEN_CFG, value: Disabled} -- {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} -- {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} - * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ -/* clang-format on */ - -/******************************************************************************* - * Variables for BOARD_BootClockFRO12M configuration - ******************************************************************************/ -/******************************************************************************* - * Code for BOARD_BootClockFRO12M configuration - ******************************************************************************/ -void BOARD_BootClockFRO12M(void) -{ - /*!< Enable SCG clock */ - CLOCK_EnableClock(kCLOCK_Scg); - - /*!< Set up clock selectors - Attach clocks to the peripheries */ - CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO12M */ - - /*!< Set up dividers */ - CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U); /*!< Set AHBCLKDIV divider to value 1 */ - - /* Set SystemCoreClock variable */ - SystemCoreClock = BOARD_BOOTCLOCKFRO12M_CORE_CLOCK; -} - -/******************************************************************************* - ******************* Configuration BOARD_BootClockFROHF48M ********************* - ******************************************************************************/ -/* clang-format off */ -/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* -!!Configuration -name: BOARD_BootClockFROHF48M -outputs: -- {id: CLK_144M_clock.outFreq, value: 144 MHz} -- {id: CLK_48M_clock.outFreq, value: 48 MHz} -- {id: FRO_12M_clock.outFreq, value: 12 MHz} -- {id: FRO_HF_clock.outFreq, value: 48 MHz} -- {id: MAIN_clock.outFreq, value: 48 MHz} -- {id: Slow_clock.outFreq, value: 12 MHz} -- {id: System_clock.outFreq, value: 48 MHz} -- {id: gdet_clock.outFreq, value: 48 MHz} -- {id: trng_clock.outFreq, value: 48 MHz} -settings: -- {id: SYSCON.FLEXCAN0CLKSEL.sel, value: NO_CLOCK} -- {id: SYSCON.FLEXCAN1CLKSEL.sel, value: NO_CLOCK} -- {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} -- {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} - * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ -/* clang-format on */ - -/******************************************************************************* - * Variables for BOARD_BootClockFROHF48M configuration - ******************************************************************************/ -/******************************************************************************* - * Code for BOARD_BootClockFROHF48M configuration - ******************************************************************************/ -void BOARD_BootClockFROHF48M(void) -{ - /*!< Enable SCG clock */ - CLOCK_EnableClock(kCLOCK_Scg); - - CLOCK_SetupFROHFClocking(48000000U); /*!< Enable FRO HF(48MHz) output */ - - /*!< Set up clock selectors - Attach clocks to the peripheries */ - CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO_HF */ - - /*!< Set up dividers */ - CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U); /*!< Set AHBCLKDIV divider to value 1 */ - - /* Set SystemCoreClock variable */ - SystemCoreClock = BOARD_BOOTCLOCKFROHF48M_CORE_CLOCK; -} - -/******************************************************************************* - ******************* Configuration BOARD_BootClockFROHF144M ******************** - ******************************************************************************/ -/* clang-format off */ -/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* -!!Configuration -name: BOARD_BootClockFROHF144M -outputs: -- {id: CLK_144M_clock.outFreq, value: 144 MHz} -- {id: CLK_48M_clock.outFreq, value: 48 MHz} -- {id: FRO_12M_clock.outFreq, value: 12 MHz} -- {id: FRO_HF_clock.outFreq, value: 144 MHz} -- {id: MAIN_clock.outFreq, value: 144 MHz} -- {id: Slow_clock.outFreq, value: 18 MHz} -- {id: System_clock.outFreq, value: 72 MHz} -- {id: gdet_clock.outFreq, value: 48 MHz} -- {id: trng_clock.outFreq, value: 48 MHz} -settings: -- {id: SYSCON.AHBCLKDIV.scale, value: '2', locked: true} -- {id: SYSCON.FLEXCAN0CLKSEL.sel, value: NO_CLOCK} -- {id: SYSCON.FLEXCAN1CLKSEL.sel, value: NO_CLOCK} -- {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} -- {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} -sources: -- {id: SCG.FIRC.outFreq, value: 144 MHz} - * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ -/* clang-format on */ - -/******************************************************************************* - * Variables for BOARD_BootClockFROHF144M configuration - ******************************************************************************/ -/******************************************************************************* - * Code for BOARD_BootClockFROHF144M configuration - ******************************************************************************/ -void BOARD_BootClockFROHF144M(void) -{ - /*!< Enable SCG clock */ - CLOCK_EnableClock(kCLOCK_Scg); - - CLOCK_SetupFROHFClocking(144000000U); /*!< Enable FRO HF(144MHz) output */ - - /*!< Set up clock selectors - Attach clocks to the peripheries */ - CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO_HF */ - - /*!< Set up dividers */ - CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 2U); /*!< Set AHBCLKDIV divider to value 2 */ - - /* Set SystemCoreClock variable */ - SystemCoreClock = BOARD_BOOTCLOCKFROHF144M_CORE_CLOCK; -} - -/******************************************************************************* - ******************** Configuration BOARD_BootClockPLL150M ********************* - ******************************************************************************/ -/* clang-format off */ -/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* -!!Configuration -name: BOARD_BootClockPLL150M -called_from_default_init: true -outputs: -- {id: CLK_144M_clock.outFreq, value: 144 MHz} -- {id: CLK_48M_clock.outFreq, value: 48 MHz} -- {id: FRO_12M_clock.outFreq, value: 12 MHz} -- {id: FRO_HF_clock.outFreq, value: 48 MHz} -- {id: MAIN_clock.outFreq, value: 150 MHz} -- {id: PLL0_CLK_clock.outFreq, value: 150 MHz} -- {id: Slow_clock.outFreq, value: 37.5 MHz} -- {id: System_clock.outFreq, value: 150 MHz} -- {id: gdet_clock.outFreq, value: 48 MHz} -- {id: trng_clock.outFreq, value: 48 MHz} -settings: -- {id: PLL0_Mode, value: Normal} -- {id: RunPowerMode, value: OD} -- {id: SCGMode, value: PLL0} -- {id: SCG.PLL0M_MULT.scale, value: '50', locked: true} -- {id: SCG.PLL0SRCSEL.sel, value: SCG.FIRC_48M} -- {id: SCG.PLL0_NDIV.scale, value: '8', locked: true} -- {id: SCG.SCSSEL.sel, value: SCG.PLL0_CLK} -- {id: SYSCON.FLEXCAN0CLKSEL.sel, value: NO_CLOCK} -- {id: SYSCON.FLEXCAN1CLKSEL.sel, value: NO_CLOCK} -- {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} -- {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} - * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ -/* clang-format on */ - -/******************************************************************************* - * Variables for BOARD_BootClockPLL150M configuration - ******************************************************************************/ -/******************************************************************************* - * Code for BOARD_BootClockPLL150M configuration - ******************************************************************************/ -void BOARD_BootClockPLL150M(void) -{ - /*!< Enable SCG clock */ - CLOCK_EnableClock(kCLOCK_Scg); - - CLOCK_SetupFROHFClocking(48000000U); /*!< Enable FRO HF(48MHz) output */ - - /*!< Set up PLL0 */ - const pll_setup_t pll0Setup = { - .pllctrl = SCG_APLLCTRL_SOURCE(1U) | SCG_APLLCTRL_SELI(27U) | SCG_APLLCTRL_SELP(13U), - .pllndiv = SCG_APLLNDIV_NDIV(8U), - .pllpdiv = SCG_APLLPDIV_PDIV(1U), - .pllmdiv = SCG_APLLMDIV_MDIV(50U), - .pllRate = 150000000U - }; - CLOCK_SetPLL0Freq(&pll0Setup); /*!< Configure PLL0 to the desired values */ - CLOCK_SetPll0MonitorMode(kSCG_Pll0MonitorDisable); /* Pll0 Monitor is disabled */ - - /*!< Set up clock selectors - Attach clocks to the peripheries */ - CLOCK_AttachClk(kPLL0_to_MAIN_CLK); /*!< Switch MAIN_CLK to PLL0 */ - - /*!< Set up dividers */ - CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U); /*!< Set AHBCLKDIV divider to value 1 */ - - /* Set SystemCoreClock variable */ - SystemCoreClock = BOARD_BOOTCLOCKPLL150M_CORE_CLOCK; -} - -/******************************************************************************* - ******************** Configuration BOARD_BootClockPLL100M ********************* - ******************************************************************************/ -/* clang-format off */ -/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* -!!Configuration -name: BOARD_BootClockPLL100M -outputs: -- {id: CLK_144M_clock.outFreq, value: 144 MHz} -- {id: CLK_48M_clock.outFreq, value: 48 MHz} -- {id: CLK_IN_clock.outFreq, value: 24 MHz} -- {id: FRO_12M_clock.outFreq, value: 12 MHz} -- {id: MAIN_clock.outFreq, value: 100 MHz} -- {id: PLL1_CLK_clock.outFreq, value: 100 MHz} -- {id: Slow_clock.outFreq, value: 25 MHz} -- {id: System_clock.outFreq, value: 100 MHz} -- {id: gdet_clock.outFreq, value: 48 MHz} -- {id: trng_clock.outFreq, value: 48 MHz} -settings: -- {id: PLL1_Mode, value: Normal} -- {id: SCGMode, value: PLL1} -- {id: SCG.PLL1M_MULT.scale, value: '100', locked: true} -- {id: SCG.PLL1_NDIV.scale, value: '6', locked: true} -- {id: SCG.PLL1_PDIV.scale, value: '4', locked: true} -- {id: SCG.SCSSEL.sel, value: SCG.PLL1_CLK} -- {id: SCG_FIRCCSR_FIRCEN_CFG, value: Disabled} -- {id: SCG_SOSCCSR_SOSCEN_CFG, value: Enabled} -- {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} -- {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} -sources: -- {id: SCG.SOSC.outFreq, value: 24 MHz, enabled: true} - * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ -/* clang-format on */ - -/******************************************************************************* - * Variables for BOARD_BootClockPLL100M configuration - ******************************************************************************/ -/******************************************************************************* - * Code for BOARD_BootClockPLL100M configuration - ******************************************************************************/ -void BOARD_BootClockPLL100M(void) -{ - /*!< Enable SCG clock */ - CLOCK_EnableClock(kCLOCK_Scg); - - CLOCK_SetupExtClocking(24000000U); - CLOCK_SetSysOscMonitorMode(kSCG_SysOscMonitorDisable); /* System OSC Clock Monitor is disabled */ - - /*!< Set up PLL1 */ - const pll_setup_t pll1Setup = { - .pllctrl = SCG_SPLLCTRL_SOURCE(0U) | SCG_SPLLCTRL_SELI(53U) | SCG_SPLLCTRL_SELP(26U), - .pllndiv = SCG_SPLLNDIV_NDIV(6U), - .pllpdiv = SCG_SPLLPDIV_PDIV(2U), - .pllmdiv = SCG_SPLLMDIV_MDIV(100U), - .pllRate = 100000000U - }; - CLOCK_SetPLL1Freq(&pll1Setup); /*!< Configure PLL1 to the desired values */ - CLOCK_SetPll1MonitorMode(kSCG_Pll1MonitorDisable); /* Pll1 Monitor is disabled */ - - /*!< Set up clock selectors - Attach clocks to the peripheries */ - CLOCK_AttachClk(kPLL1_to_MAIN_CLK); /*!< Switch MAIN_CLK to PLL1 */ - - /*!< Set up dividers */ - CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U); /*!< Set AHBCLKDIV divider to value 1 */ - - /* Set SystemCoreClock variable */ - SystemCoreClock = BOARD_BOOTCLOCKPLL100M_CORE_CLOCK; -} diff --git a/hw/bsp/mcx/boards/bunny-brain/clock_config.h b/hw/bsp/mcx/boards/bunny-brain/clock_config.h deleted file mode 100644 index c238a0423..000000000 --- a/hw/bsp/mcx/boards/bunny-brain/clock_config.h +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright 2022 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/*********************************************************************************************************************** - * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file - * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. - **********************************************************************************************************************/ - -#ifndef _CLOCK_CONFIG_H_ -#define _CLOCK_CONFIG_H_ - -#include "fsl_common.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ -#define BOARD_XTAL0_CLK_HZ 24000000U /*!< Board xtal frequency in Hz */ -#define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32K frequency in Hz */ - -/******************************************************************************* - ************************ BOARD_InitBootClocks function ************************ - ******************************************************************************/ - -#if defined(__cplusplus) -extern "C" { -#endif /* __cplusplus*/ - -/*! - * @brief This function executes default configuration of clocks. - * - */ -void BOARD_InitBootClocks(void); - -#if defined(__cplusplus) -} -#endif /* __cplusplus*/ - -/******************************************************************************* - ******************** Configuration BOARD_BootClockFRO12M ********************** - ******************************************************************************/ -/******************************************************************************* - * Definitions for BOARD_BootClockFRO12M configuration - ******************************************************************************/ -#define BOARD_BOOTCLOCKFRO12M_CORE_CLOCK 12000000U /*!< Core clock frequency: 12000000Hz */ -#define BOARD_BOOTCLOCKFRO12M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ - - -/******************************************************************************* - * API for BOARD_BootClockFRO12M configuration - ******************************************************************************/ -#if defined(__cplusplus) -extern "C" { -#endif /* __cplusplus*/ - -/*! - * @brief This function executes configuration of clocks. - * - */ -void BOARD_BootClockFRO12M(void); - -#if defined(__cplusplus) -} -#endif /* __cplusplus*/ - -/******************************************************************************* - ******************* Configuration BOARD_BootClockFROHF48M ********************* - ******************************************************************************/ -/******************************************************************************* - * Definitions for BOARD_BootClockFROHF48M configuration - ******************************************************************************/ -#define BOARD_BOOTCLOCKFROHF48M_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */ -#define BOARD_BOOTCLOCKFROHF48M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ - - -/******************************************************************************* - * API for BOARD_BootClockFROHF48M configuration - ******************************************************************************/ -#if defined(__cplusplus) -extern "C" { -#endif /* __cplusplus*/ - -/*! - * @brief This function executes configuration of clocks. - * - */ -void BOARD_BootClockFROHF48M(void); - -#if defined(__cplusplus) -} -#endif /* __cplusplus*/ - -/******************************************************************************* - ******************* Configuration BOARD_BootClockFROHF144M ******************** - ******************************************************************************/ -/******************************************************************************* - * Definitions for BOARD_BootClockFROHF144M configuration - ******************************************************************************/ -#define BOARD_BOOTCLOCKFROHF144M_CORE_CLOCK 144000000U /*!< Core clock frequency: 144000000Hz */ -#define BOARD_BOOTCLOCKFROHF144M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ - - -/******************************************************************************* - * API for BOARD_BootClockFROHF144M configuration - ******************************************************************************/ -#if defined(__cplusplus) -extern "C" { -#endif /* __cplusplus*/ - -/*! - * @brief This function executes configuration of clocks. - * - */ -void BOARD_BootClockFROHF144M(void); - -#if defined(__cplusplus) -} -#endif /* __cplusplus*/ - -/******************************************************************************* - ******************** Configuration BOARD_BootClockPLL150M ********************* - ******************************************************************************/ -/******************************************************************************* - * Definitions for BOARD_BootClockPLL150M configuration - ******************************************************************************/ -#define BOARD_BOOTCLOCKPLL150M_CORE_CLOCK 150000000U /*!< Core clock frequency: 150000000Hz */ -#define BOARD_BOOTCLOCKPLL150M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ - - -/******************************************************************************* - * API for BOARD_BootClockPLL150M configuration - ******************************************************************************/ -#if defined(__cplusplus) -extern "C" { -#endif /* __cplusplus*/ - -/*! - * @brief This function executes configuration of clocks. - * - */ -void BOARD_BootClockPLL150M(void); - -#if defined(__cplusplus) -} -#endif /* __cplusplus*/ - -/******************************************************************************* - ******************** Configuration BOARD_BootClockPLL100M ********************* - ******************************************************************************/ -/******************************************************************************* - * Definitions for BOARD_BootClockPLL100M configuration - ******************************************************************************/ -#define BOARD_BOOTCLOCKPLL100M_CORE_CLOCK 100000000U /*!< Core clock frequency: 100000000Hz */ -#define BOARD_BOOTCLOCKPLL100M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ - - -/******************************************************************************* - * API for BOARD_BootClockPLL100M configuration - ******************************************************************************/ -#if defined(__cplusplus) -extern "C" { -#endif /* __cplusplus*/ - -/*! - * @brief This function executes configuration of clocks. - * - */ -void BOARD_BootClockPLL100M(void); - -#if defined(__cplusplus) -} -#endif /* __cplusplus*/ - -#endif /* _CLOCK_CONFIG_H_ */ diff --git a/hw/bsp/mcx/boards/bunny-brain/pin_mux.c b/hw/bsp/mcx/boards/bunny-brain/pin_mux.c deleted file mode 100644 index acc2f3e45..000000000 --- a/hw/bsp/mcx/boards/bunny-brain/pin_mux.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright 2022 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ -/*********************************************************************************************************************** - * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file - * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. - **********************************************************************************************************************/ - -/* clang-format off */ -/* - * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* -!!GlobalInfo -product: Pins v12.0 -processor: MCXN947 -package_id: MCXN947VDF -mcu_data: ksdk2_0 -processor_version: 0.12.3 - * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** - */ -/* clang-format on */ - -#include "fsl_common.h" -#include "fsl_port.h" -#include "pin_mux.h" - -/* FUNCTION ************************************************************************************************************ - * - * Function Name : BOARD_InitBootPins - * Description : Calls initialization functions. - * - * END ****************************************************************************************************************/ -void BOARD_InitBootPins(void) -{ - BOARD_InitPins(); -} - -/* clang-format off */ -/* - * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* -BOARD_InitPins: -- options: {callFromInitBoot: 'true', coreID: cm33_core0, enableClock: 'true'} -- pin_list: - - {pin_num: A1, peripheral: LPFlexcomm4, signal: LPFLEXCOMM_P0, pin_signal: PIO1_8/WUU0_IN10/LPTMR1_ALT3/TRACE_DATA0/FC4_P0/FC5_P4/CT_INP8/SCT0_OUT2/FLEXIO0_D16/PLU_OUT0/ENET0_TXD2/I3C1_SDA/TSI0_CH17/ADC1_A8, - slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable, pull_value: low, input_buffer: enable, - invert_input: normal} - - {pin_num: B1, peripheral: LPFlexcomm4, signal: LPFLEXCOMM_P1, pin_signal: PIO1_9/TRACE_DATA1/FC4_P1/FC5_P5/CT_INP9/SCT0_OUT3/FLEXIO0_D17/PLU_OUT1/ENET0_TXD3/I3C1_SCL/TSI0_CH18/ADC1_A9, - slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable, input_buffer: enable, invert_input: normal} - - {pin_num: F14, peripheral: GPIO3, signal: 'GPIO, 4', pin_signal: PIO3_4/FC7_P2/CT_INP18/PWM0_X2/FLEXIO0_D12/SIM1_CLK, slew_rate: fast, open_drain: disable, drive_strength: low, - pull_select: down, pull_enable: disable, input_buffer: enable, invert_input: normal} - * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** - */ -/* clang-format on */ - -/* FUNCTION ************************************************************************************************************ - * - * Function Name : BOARD_InitPins - * Description : Configures pin routing and optionally pin electrical features. - * - * END ****************************************************************************************************************/ -void BOARD_InitPins(void) -{ - /* Enables the clock for PORT1: Enables clock */ - CLOCK_EnableClock(kCLOCK_Port1); - /* Enables the clock for PORT3: Enables clock */ - CLOCK_EnableClock(kCLOCK_Port3); - - const port_pin_config_t port1_8_pinA1_config = {/* Internal pull-up/down resistor is disabled */ - kPORT_PullDisable, - /* Low internal pull resistor value is selected. */ - kPORT_LowPullResistor, - /* Fast slew rate is configured */ - kPORT_FastSlewRate, - /* Passive input filter is disabled */ - kPORT_PassiveFilterDisable, - /* Open drain output is disabled */ - kPORT_OpenDrainDisable, - /* Low drive strength is configured */ - kPORT_LowDriveStrength, - /* Pin is configured as FC4_P0 */ - kPORT_MuxAlt2, - /* Digital input enabled */ - kPORT_InputBufferEnable, - /* Digital input is not inverted */ - kPORT_InputNormal, - /* Pin Control Register fields [15:0] are not locked */ - kPORT_UnlockRegister}; - /* PORT1_8 (pin A1) is configured as FC4_P0 */ - PORT_SetPinConfig(PORT1, 8U, &port1_8_pinA1_config); - - const port_pin_config_t port1_9_pinB1_config = {/* Internal pull-up/down resistor is disabled */ - kPORT_PullDisable, - /* Low internal pull resistor value is selected. */ - kPORT_LowPullResistor, - /* Fast slew rate is configured */ - kPORT_FastSlewRate, - /* Passive input filter is disabled */ - kPORT_PassiveFilterDisable, - /* Open drain output is disabled */ - kPORT_OpenDrainDisable, - /* Low drive strength is configured */ - kPORT_LowDriveStrength, - /* Pin is configured as FC4_P1 */ - kPORT_MuxAlt2, - /* Digital input enabled */ - kPORT_InputBufferEnable, - /* Digital input is not inverted */ - kPORT_InputNormal, - /* Pin Control Register fields [15:0] are not locked */ - kPORT_UnlockRegister}; - /* PORT1_9 (pin B1) is configured as FC4_P1 */ - PORT_SetPinConfig(PORT1, 9U, &port1_9_pinB1_config); - - const port_pin_config_t port3_4_pinF14_config = {/* Internal pull-up/down resistor is disabled */ - kPORT_PullDisable, - /* Low internal pull resistor value is selected. */ - kPORT_LowPullResistor, - /* Fast slew rate is configured */ - kPORT_FastSlewRate, - /* Passive input filter is disabled */ - kPORT_PassiveFilterDisable, - /* Open drain output is disabled */ - kPORT_OpenDrainDisable, - /* Low drive strength is configured */ - kPORT_LowDriveStrength, - /* Pin is configured as PIO3_4 */ - kPORT_MuxAlt0, - /* Digital input enabled */ - kPORT_InputBufferEnable, - /* Digital input is not inverted */ - kPORT_InputNormal, - /* Pin Control Register fields [15:0] are not locked */ - kPORT_UnlockRegister}; - /* PORT3_4 (pin F14) is configured as PIO3_4 */ - PORT_SetPinConfig(PORT3, 4U, &port3_4_pinF14_config); -} -/*********************************************************************************************************************** - * EOF - **********************************************************************************************************************/ diff --git a/hw/bsp/mcx/boards/bunny-brain/pin_mux.h b/hw/bsp/mcx/boards/bunny-brain/pin_mux.h deleted file mode 100644 index 40968c275..000000000 --- a/hw/bsp/mcx/boards/bunny-brain/pin_mux.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2022 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ -/*********************************************************************************************************************** - * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file - * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. - **********************************************************************************************************************/ - -#ifndef _PIN_MUX_H_ -#define _PIN_MUX_H_ - -/*! - * @addtogroup pin_mux - * @{ - */ - -/*********************************************************************************************************************** - * API - **********************************************************************************************************************/ - -#if defined(__cplusplus) -extern "C" { -#endif - -/*! - * @brief Calls initialization functions. - * - */ -void BOARD_InitBootPins(void); - -/*! - * @brief Configures pin routing and optionally pin electrical features. - * - */ -void BOARD_InitPins(void); - -#if defined(__cplusplus) -} -#endif - -/*! - * @} - */ -#endif /* _PIN_MUX_H_ */ - -/*********************************************************************************************************************** - * EOF - **********************************************************************************************************************/ diff --git a/hw/bsp/mcx/boards/frdm-mcxn947/board.cmake b/hw/bsp/mcx/boards/frdm-mcxn947/board.cmake deleted file mode 100644 index 8c3280743..000000000 --- a/hw/bsp/mcx/boards/frdm-mcxn947/board.cmake +++ /dev/null @@ -1,21 +0,0 @@ -set(MCU_VARIANT MCXN947) -set(MCU_CORE MCXN947_cm33_core0) - -set(JLINK_DEVICE MCXN947_M33_0) -set(PYOCD_TARGET MCXN947) -set(NXPLINK_DEVICE MCXN947:MCXN947) - -set(PORT 1) - -function(update_board TARGET) - target_compile_definitions(${TARGET} PUBLIC - CPU_MCXN947VDF_cm33_core0 - BOARD_TUD_RHPORT=${PORT} - # port 0 is fullspeed, port 1 is highspeed - BOARD_TUD_MAX_SPEED=$ - ) - target_sources(${TARGET} PUBLIC - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/clock_config.c - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/pin_mux.c - ) -endfunction() diff --git a/hw/bsp/mcx/boards/frdm-mcxn947/board.h b/hw/bsp/mcx/boards/frdm-mcxn947/board.h deleted file mode 100644 index acb73363f..000000000 --- a/hw/bsp/mcx/boards/frdm-mcxn947/board.h +++ /dev/null @@ -1,66 +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 - -// LED -#define LED_GPIO GPIO0 -#define LED_CLK kCLOCK_Gpio0 -#define LED_PIN 10 // red -#define LED_STATE_ON 0 - -// WAKE button (Dummy, use unused pin -#define BUTTON_GPIO GPIO0 -#define BUTTON_CLK kCLOCK_Gpio0 -#define BUTTON_PIN 23 -#define BUTTON_STATE_ACTIVE 0 - -// UART -#define UART_DEV LPUART4 - -static inline void board_uart_init_clock(void) { - /* attach FRO 12M to FLEXCOMM4 */ - CLOCK_SetClkDiv(kCLOCK_DivFlexcom4Clk, 1u); - CLOCK_AttachClk(kFRO12M_to_FLEXCOMM4); - RESET_ClearPeripheralReset(kFC4_RST_SHIFT_RSTn); -} - -//#define UART_RX_PINMUX 0, 24, IOCON_PIO_DIG_FUNC1_EN -//#define UART_TX_PINMUX 0, 25, IOCON_PIO_DIG_FUNC1_EN - -// XTAL -#define XTAL0_CLK_HZ (24 * 1000 * 1000U) - -#ifdef __cplusplus - } -#endif - -#endif diff --git a/hw/bsp/mcx/boards/frdm-mcxn947/board.mk b/hw/bsp/mcx/boards/frdm-mcxn947/board.mk deleted file mode 100644 index aaad5e73e..000000000 --- a/hw/bsp/mcx/boards/frdm-mcxn947/board.mk +++ /dev/null @@ -1,11 +0,0 @@ -MCU_VARIANT = MCXN947 -MCU_CORE = MCXN947_cm33_core0 -PORT ?= 1 - -CFLAGS += -DCPU_MCXN947VDF_cm33_core0 - -JLINK_DEVICE = MCXN947_M33_0 -PYOCD_TARGET = MCXN947 - -# flash using pyocd -flash: flash-jlink diff --git a/hw/bsp/mcx/boards/frdm-mcxn947/clock_config.c b/hw/bsp/mcx/boards/frdm-mcxn947/clock_config.c deleted file mode 100644 index 37d2b4dfc..000000000 --- a/hw/bsp/mcx/boards/frdm-mcxn947/clock_config.c +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Copyright 2022 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/*********************************************************************************************************************** - * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file - * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. - **********************************************************************************************************************/ -/* - * How to setup clock using clock driver functions: - * - * 1. Setup clock sources. - * - * 2. Set up wait states of the flash. - * - * 3. Set up all dividers. - * - * 4. Set up all selectors to provide selected clocks. - * - */ - -/* clang-format off */ -/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* -!!GlobalInfo -product: Clocks v10.0 -processor: MCXN947 -package_id: MCXN947VDF -mcu_data: ksdk2_0 -processor_version: 0.12.3 -board: MCX-N9XX-EVK - * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ -/* clang-format on */ - -#include "clock_config.h" -#include "fsl_clock.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/******************************************************************************* - * Variables - ******************************************************************************/ -/* System clock frequency. */ -// extern uint32_t SystemCoreClock; - -/******************************************************************************* - ************************ BOARD_InitBootClocks function ************************ - ******************************************************************************/ -void BOARD_InitBootClocks(void) -{ - BOARD_BootClockPLL150M(); -} - -/******************************************************************************* - ******************** Configuration BOARD_BootClockFRO12M ********************** - ******************************************************************************/ -/* clang-format off */ -/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* -!!Configuration -name: BOARD_BootClockFRO12M -outputs: -- {id: CLK_144M_clock.outFreq, value: 144 MHz} -- {id: CLK_48M_clock.outFreq, value: 48 MHz} -- {id: FRO_12M_clock.outFreq, value: 12 MHz} -- {id: MAIN_clock.outFreq, value: 12 MHz} -- {id: Slow_clock.outFreq, value: 3 MHz} -- {id: System_clock.outFreq, value: 12 MHz} -- {id: gdet_clock.outFreq, value: 48 MHz} -- {id: trng_clock.outFreq, value: 48 MHz} -settings: -- {id: SCGMode, value: SIRC} -- {id: SCG.SCSSEL.sel, value: SCG.SIRC} -- {id: SCG_FIRCCSR_FIRCEN_CFG, value: Disabled} -- {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} -- {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} - * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ -/* clang-format on */ - -/******************************************************************************* - * Variables for BOARD_BootClockFRO12M configuration - ******************************************************************************/ -/******************************************************************************* - * Code for BOARD_BootClockFRO12M configuration - ******************************************************************************/ -void BOARD_BootClockFRO12M(void) -{ - /*!< Enable SCG clock */ - CLOCK_EnableClock(kCLOCK_Scg); - - /*!< Set up clock selectors - Attach clocks to the peripheries */ - CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO12M */ - - /*!< Set up dividers */ - CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U); /*!< Set AHBCLKDIV divider to value 1 */ - - /* Set SystemCoreClock variable */ - SystemCoreClock = BOARD_BOOTCLOCKFRO12M_CORE_CLOCK; -} - -/******************************************************************************* - ******************* Configuration BOARD_BootClockFROHF48M ********************* - ******************************************************************************/ -/* clang-format off */ -/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* -!!Configuration -name: BOARD_BootClockFROHF48M -outputs: -- {id: CLK_144M_clock.outFreq, value: 144 MHz} -- {id: CLK_48M_clock.outFreq, value: 48 MHz} -- {id: FRO_12M_clock.outFreq, value: 12 MHz} -- {id: FRO_HF_clock.outFreq, value: 48 MHz} -- {id: MAIN_clock.outFreq, value: 48 MHz} -- {id: Slow_clock.outFreq, value: 12 MHz} -- {id: System_clock.outFreq, value: 48 MHz} -- {id: gdet_clock.outFreq, value: 48 MHz} -- {id: trng_clock.outFreq, value: 48 MHz} -settings: -- {id: SYSCON.FLEXCAN0CLKSEL.sel, value: NO_CLOCK} -- {id: SYSCON.FLEXCAN1CLKSEL.sel, value: NO_CLOCK} -- {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} -- {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} - * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ -/* clang-format on */ - -/******************************************************************************* - * Variables for BOARD_BootClockFROHF48M configuration - ******************************************************************************/ -/******************************************************************************* - * Code for BOARD_BootClockFROHF48M configuration - ******************************************************************************/ -void BOARD_BootClockFROHF48M(void) -{ - /*!< Enable SCG clock */ - CLOCK_EnableClock(kCLOCK_Scg); - - CLOCK_SetupFROHFClocking(48000000U); /*!< Enable FRO HF(48MHz) output */ - - /*!< Set up clock selectors - Attach clocks to the peripheries */ - CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO_HF */ - - /*!< Set up dividers */ - CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U); /*!< Set AHBCLKDIV divider to value 1 */ - - /* Set SystemCoreClock variable */ - SystemCoreClock = BOARD_BOOTCLOCKFROHF48M_CORE_CLOCK; -} - -/******************************************************************************* - ******************* Configuration BOARD_BootClockFROHF144M ******************** - ******************************************************************************/ -/* clang-format off */ -/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* -!!Configuration -name: BOARD_BootClockFROHF144M -outputs: -- {id: CLK_144M_clock.outFreq, value: 144 MHz} -- {id: CLK_48M_clock.outFreq, value: 48 MHz} -- {id: FRO_12M_clock.outFreq, value: 12 MHz} -- {id: FRO_HF_clock.outFreq, value: 144 MHz} -- {id: MAIN_clock.outFreq, value: 144 MHz} -- {id: Slow_clock.outFreq, value: 18 MHz} -- {id: System_clock.outFreq, value: 72 MHz} -- {id: gdet_clock.outFreq, value: 48 MHz} -- {id: trng_clock.outFreq, value: 48 MHz} -settings: -- {id: SYSCON.AHBCLKDIV.scale, value: '2', locked: true} -- {id: SYSCON.FLEXCAN0CLKSEL.sel, value: NO_CLOCK} -- {id: SYSCON.FLEXCAN1CLKSEL.sel, value: NO_CLOCK} -- {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} -- {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} -sources: -- {id: SCG.FIRC.outFreq, value: 144 MHz} - * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ -/* clang-format on */ - -/******************************************************************************* - * Variables for BOARD_BootClockFROHF144M configuration - ******************************************************************************/ -/******************************************************************************* - * Code for BOARD_BootClockFROHF144M configuration - ******************************************************************************/ -void BOARD_BootClockFROHF144M(void) -{ - /*!< Enable SCG clock */ - CLOCK_EnableClock(kCLOCK_Scg); - - CLOCK_SetupFROHFClocking(144000000U); /*!< Enable FRO HF(144MHz) output */ - - /*!< Set up clock selectors - Attach clocks to the peripheries */ - CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO_HF */ - - /*!< Set up dividers */ - CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 2U); /*!< Set AHBCLKDIV divider to value 2 */ - - /* Set SystemCoreClock variable */ - SystemCoreClock = BOARD_BOOTCLOCKFROHF144M_CORE_CLOCK; -} - -/******************************************************************************* - ******************** Configuration BOARD_BootClockPLL150M ********************* - ******************************************************************************/ -/* clang-format off */ -/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* -!!Configuration -name: BOARD_BootClockPLL150M -called_from_default_init: true -outputs: -- {id: CLK_144M_clock.outFreq, value: 144 MHz} -- {id: CLK_48M_clock.outFreq, value: 48 MHz} -- {id: FRO_12M_clock.outFreq, value: 12 MHz} -- {id: FRO_HF_clock.outFreq, value: 48 MHz} -- {id: MAIN_clock.outFreq, value: 150 MHz} -- {id: PLL0_CLK_clock.outFreq, value: 150 MHz} -- {id: Slow_clock.outFreq, value: 37.5 MHz} -- {id: System_clock.outFreq, value: 150 MHz} -- {id: gdet_clock.outFreq, value: 48 MHz} -- {id: trng_clock.outFreq, value: 48 MHz} -settings: -- {id: PLL0_Mode, value: Normal} -- {id: RunPowerMode, value: OD} -- {id: SCGMode, value: PLL0} -- {id: SCG.PLL0M_MULT.scale, value: '50', locked: true} -- {id: SCG.PLL0SRCSEL.sel, value: SCG.FIRC_48M} -- {id: SCG.PLL0_NDIV.scale, value: '8', locked: true} -- {id: SCG.SCSSEL.sel, value: SCG.PLL0_CLK} -- {id: SYSCON.FLEXCAN0CLKSEL.sel, value: NO_CLOCK} -- {id: SYSCON.FLEXCAN1CLKSEL.sel, value: NO_CLOCK} -- {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} -- {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} - * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ -/* clang-format on */ - -/******************************************************************************* - * Variables for BOARD_BootClockPLL150M configuration - ******************************************************************************/ -/******************************************************************************* - * Code for BOARD_BootClockPLL150M configuration - ******************************************************************************/ -void BOARD_BootClockPLL150M(void) -{ - /*!< Enable SCG clock */ - CLOCK_EnableClock(kCLOCK_Scg); - - CLOCK_SetupFROHFClocking(48000000U); /*!< Enable FRO HF(48MHz) output */ - - /*!< Set up PLL0 */ - const pll_setup_t pll0Setup = { - .pllctrl = SCG_APLLCTRL_SOURCE(1U) | SCG_APLLCTRL_SELI(27U) | SCG_APLLCTRL_SELP(13U), - .pllndiv = SCG_APLLNDIV_NDIV(8U), - .pllpdiv = SCG_APLLPDIV_PDIV(1U), - .pllmdiv = SCG_APLLMDIV_MDIV(50U), - .pllRate = 150000000U - }; - CLOCK_SetPLL0Freq(&pll0Setup); /*!< Configure PLL0 to the desired values */ - CLOCK_SetPll0MonitorMode(kSCG_Pll0MonitorDisable); /* Pll0 Monitor is disabled */ - - /*!< Set up clock selectors - Attach clocks to the peripheries */ - CLOCK_AttachClk(kPLL0_to_MAIN_CLK); /*!< Switch MAIN_CLK to PLL0 */ - - /*!< Set up dividers */ - CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U); /*!< Set AHBCLKDIV divider to value 1 */ - - /* Set SystemCoreClock variable */ - SystemCoreClock = BOARD_BOOTCLOCKPLL150M_CORE_CLOCK; -} - -/******************************************************************************* - ******************** Configuration BOARD_BootClockPLL100M ********************* - ******************************************************************************/ -/* clang-format off */ -/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* -!!Configuration -name: BOARD_BootClockPLL100M -outputs: -- {id: CLK_144M_clock.outFreq, value: 144 MHz} -- {id: CLK_48M_clock.outFreq, value: 48 MHz} -- {id: CLK_IN_clock.outFreq, value: 24 MHz} -- {id: FRO_12M_clock.outFreq, value: 12 MHz} -- {id: MAIN_clock.outFreq, value: 100 MHz} -- {id: PLL1_CLK_clock.outFreq, value: 100 MHz} -- {id: Slow_clock.outFreq, value: 25 MHz} -- {id: System_clock.outFreq, value: 100 MHz} -- {id: gdet_clock.outFreq, value: 48 MHz} -- {id: trng_clock.outFreq, value: 48 MHz} -settings: -- {id: PLL1_Mode, value: Normal} -- {id: SCGMode, value: PLL1} -- {id: SCG.PLL1M_MULT.scale, value: '100', locked: true} -- {id: SCG.PLL1_NDIV.scale, value: '6', locked: true} -- {id: SCG.PLL1_PDIV.scale, value: '4', locked: true} -- {id: SCG.SCSSEL.sel, value: SCG.PLL1_CLK} -- {id: SCG_FIRCCSR_FIRCEN_CFG, value: Disabled} -- {id: SCG_SOSCCSR_SOSCEN_CFG, value: Enabled} -- {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} -- {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} -sources: -- {id: SCG.SOSC.outFreq, value: 24 MHz, enabled: true} - * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ -/* clang-format on */ - -/******************************************************************************* - * Variables for BOARD_BootClockPLL100M configuration - ******************************************************************************/ -/******************************************************************************* - * Code for BOARD_BootClockPLL100M configuration - ******************************************************************************/ -void BOARD_BootClockPLL100M(void) -{ - /*!< Enable SCG clock */ - CLOCK_EnableClock(kCLOCK_Scg); - - CLOCK_SetupExtClocking(24000000U); - CLOCK_SetSysOscMonitorMode(kSCG_SysOscMonitorDisable); /* System OSC Clock Monitor is disabled */ - - /*!< Set up PLL1 */ - const pll_setup_t pll1Setup = { - .pllctrl = SCG_SPLLCTRL_SOURCE(0U) | SCG_SPLLCTRL_SELI(53U) | SCG_SPLLCTRL_SELP(26U), - .pllndiv = SCG_SPLLNDIV_NDIV(6U), - .pllpdiv = SCG_SPLLPDIV_PDIV(2U), - .pllmdiv = SCG_SPLLMDIV_MDIV(100U), - .pllRate = 100000000U - }; - CLOCK_SetPLL1Freq(&pll1Setup); /*!< Configure PLL1 to the desired values */ - CLOCK_SetPll1MonitorMode(kSCG_Pll1MonitorDisable); /* Pll1 Monitor is disabled */ - - /*!< Set up clock selectors - Attach clocks to the peripheries */ - CLOCK_AttachClk(kPLL1_to_MAIN_CLK); /*!< Switch MAIN_CLK to PLL1 */ - - /*!< Set up dividers */ - CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U); /*!< Set AHBCLKDIV divider to value 1 */ - - /* Set SystemCoreClock variable */ - SystemCoreClock = BOARD_BOOTCLOCKPLL100M_CORE_CLOCK; -} diff --git a/hw/bsp/mcx/boards/frdm-mcxn947/clock_config.h b/hw/bsp/mcx/boards/frdm-mcxn947/clock_config.h deleted file mode 100644 index c238a0423..000000000 --- a/hw/bsp/mcx/boards/frdm-mcxn947/clock_config.h +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright 2022 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/*********************************************************************************************************************** - * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file - * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. - **********************************************************************************************************************/ - -#ifndef _CLOCK_CONFIG_H_ -#define _CLOCK_CONFIG_H_ - -#include "fsl_common.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ -#define BOARD_XTAL0_CLK_HZ 24000000U /*!< Board xtal frequency in Hz */ -#define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32K frequency in Hz */ - -/******************************************************************************* - ************************ BOARD_InitBootClocks function ************************ - ******************************************************************************/ - -#if defined(__cplusplus) -extern "C" { -#endif /* __cplusplus*/ - -/*! - * @brief This function executes default configuration of clocks. - * - */ -void BOARD_InitBootClocks(void); - -#if defined(__cplusplus) -} -#endif /* __cplusplus*/ - -/******************************************************************************* - ******************** Configuration BOARD_BootClockFRO12M ********************** - ******************************************************************************/ -/******************************************************************************* - * Definitions for BOARD_BootClockFRO12M configuration - ******************************************************************************/ -#define BOARD_BOOTCLOCKFRO12M_CORE_CLOCK 12000000U /*!< Core clock frequency: 12000000Hz */ -#define BOARD_BOOTCLOCKFRO12M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ - - -/******************************************************************************* - * API for BOARD_BootClockFRO12M configuration - ******************************************************************************/ -#if defined(__cplusplus) -extern "C" { -#endif /* __cplusplus*/ - -/*! - * @brief This function executes configuration of clocks. - * - */ -void BOARD_BootClockFRO12M(void); - -#if defined(__cplusplus) -} -#endif /* __cplusplus*/ - -/******************************************************************************* - ******************* Configuration BOARD_BootClockFROHF48M ********************* - ******************************************************************************/ -/******************************************************************************* - * Definitions for BOARD_BootClockFROHF48M configuration - ******************************************************************************/ -#define BOARD_BOOTCLOCKFROHF48M_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */ -#define BOARD_BOOTCLOCKFROHF48M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ - - -/******************************************************************************* - * API for BOARD_BootClockFROHF48M configuration - ******************************************************************************/ -#if defined(__cplusplus) -extern "C" { -#endif /* __cplusplus*/ - -/*! - * @brief This function executes configuration of clocks. - * - */ -void BOARD_BootClockFROHF48M(void); - -#if defined(__cplusplus) -} -#endif /* __cplusplus*/ - -/******************************************************************************* - ******************* Configuration BOARD_BootClockFROHF144M ******************** - ******************************************************************************/ -/******************************************************************************* - * Definitions for BOARD_BootClockFROHF144M configuration - ******************************************************************************/ -#define BOARD_BOOTCLOCKFROHF144M_CORE_CLOCK 144000000U /*!< Core clock frequency: 144000000Hz */ -#define BOARD_BOOTCLOCKFROHF144M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ - - -/******************************************************************************* - * API for BOARD_BootClockFROHF144M configuration - ******************************************************************************/ -#if defined(__cplusplus) -extern "C" { -#endif /* __cplusplus*/ - -/*! - * @brief This function executes configuration of clocks. - * - */ -void BOARD_BootClockFROHF144M(void); - -#if defined(__cplusplus) -} -#endif /* __cplusplus*/ - -/******************************************************************************* - ******************** Configuration BOARD_BootClockPLL150M ********************* - ******************************************************************************/ -/******************************************************************************* - * Definitions for BOARD_BootClockPLL150M configuration - ******************************************************************************/ -#define BOARD_BOOTCLOCKPLL150M_CORE_CLOCK 150000000U /*!< Core clock frequency: 150000000Hz */ -#define BOARD_BOOTCLOCKPLL150M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ - - -/******************************************************************************* - * API for BOARD_BootClockPLL150M configuration - ******************************************************************************/ -#if defined(__cplusplus) -extern "C" { -#endif /* __cplusplus*/ - -/*! - * @brief This function executes configuration of clocks. - * - */ -void BOARD_BootClockPLL150M(void); - -#if defined(__cplusplus) -} -#endif /* __cplusplus*/ - -/******************************************************************************* - ******************** Configuration BOARD_BootClockPLL100M ********************* - ******************************************************************************/ -/******************************************************************************* - * Definitions for BOARD_BootClockPLL100M configuration - ******************************************************************************/ -#define BOARD_BOOTCLOCKPLL100M_CORE_CLOCK 100000000U /*!< Core clock frequency: 100000000Hz */ -#define BOARD_BOOTCLOCKPLL100M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ - - -/******************************************************************************* - * API for BOARD_BootClockPLL100M configuration - ******************************************************************************/ -#if defined(__cplusplus) -extern "C" { -#endif /* __cplusplus*/ - -/*! - * @brief This function executes configuration of clocks. - * - */ -void BOARD_BootClockPLL100M(void); - -#if defined(__cplusplus) -} -#endif /* __cplusplus*/ - -#endif /* _CLOCK_CONFIG_H_ */ diff --git a/hw/bsp/mcx/boards/frdm-mcxn947/pin_mux.c b/hw/bsp/mcx/boards/frdm-mcxn947/pin_mux.c deleted file mode 100644 index 30a5ae456..000000000 --- a/hw/bsp/mcx/boards/frdm-mcxn947/pin_mux.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2022 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ -/*********************************************************************************************************************** - * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file - * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. - **********************************************************************************************************************/ - -/* clang-format off */ -/* - * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* -!!GlobalInfo -product: Pins v12.0 -processor: MCXN947 -package_id: MCXN947VDF -mcu_data: ksdk2_0 -processor_version: 0.12.3 - * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** - */ -/* clang-format on */ - -#include "fsl_common.h" -#include "fsl_port.h" -#include "pin_mux.h" - -/* FUNCTION ************************************************************************************************************ - * - * Function Name : BOARD_InitBootPins - * Description : Calls initialization functions. - * - * END ****************************************************************************************************************/ -void BOARD_InitBootPins(void) -{ - BOARD_InitPins(); -} - -/* clang-format off */ -/* - * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* -BOARD_InitPins: -- options: {callFromInitBoot: 'true', coreID: cm33_core0, enableClock: 'true'} -- pin_list: - - {pin_num: A1, peripheral: LPFlexcomm4, signal: LPFLEXCOMM_P0, pin_signal: PIO1_8/WUU0_IN10/LPTMR1_ALT3/TRACE_DATA0/FC4_P0/FC5_P4/CT_INP8/SCT0_OUT2/FLEXIO0_D16/PLU_OUT0/ENET0_TXD2/I3C1_SDA/TSI0_CH17/ADC1_A8, - slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable, pull_value: low, input_buffer: enable, - invert_input: normal} - - {pin_num: B1, peripheral: LPFlexcomm4, signal: LPFLEXCOMM_P1, pin_signal: PIO1_9/TRACE_DATA1/FC4_P1/FC5_P5/CT_INP9/SCT0_OUT3/FLEXIO0_D17/PLU_OUT1/ENET0_TXD3/I3C1_SCL/TSI0_CH18/ADC1_A9, - slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable, input_buffer: enable, invert_input: normal} - - {pin_num: B12, peripheral: GPIO0, signal: 'GPIO, 10', pin_signal: PIO0_12/ADC0_B10/FC0_P6/CT0O_MAT0/FLEXIO0_D2, slew_rate: fast, open_drain: disable, drive_strength: low, - pull_select: down, pull_enable: disable, input_buffer: enable, invert_input: normal} - * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** - */ -/* clang-format on */ - -/* FUNCTION ************************************************************************************************************ - * - * Function Name : BOARD_InitPins - * Description : Configures pin routing and optionally pin electrical features. - * - * END ****************************************************************************************************************/ -void BOARD_InitPins(void) -{ - /* Enables the clock for PORT0: Enables clock */ - CLOCK_EnableClock(kCLOCK_Port0); - - /* Enables the clock for PORT1: Enables clock */ - CLOCK_EnableClock(kCLOCK_Port1); - - - const port_pin_config_t port1_8_pinA1_config = {/* Internal pull-up/down resistor is disabled */ - kPORT_PullDisable, - /* Low internal pull resistor value is selected. */ - kPORT_LowPullResistor, - /* Fast slew rate is configured */ - kPORT_FastSlewRate, - /* Passive input filter is disabled */ - kPORT_PassiveFilterDisable, - /* Open drain output is disabled */ - kPORT_OpenDrainDisable, - /* Low drive strength is configured */ - kPORT_LowDriveStrength, - /* Pin is configured as FC4_P0 */ - kPORT_MuxAlt2, - /* Digital input enabled */ - kPORT_InputBufferEnable, - /* Digital input is not inverted */ - kPORT_InputNormal, - /* Pin Control Register fields [15:0] are not locked */ - kPORT_UnlockRegister}; - /* PORT1_8 (pin A1) is configured as FC4_P0 */ - PORT_SetPinConfig(PORT1, 8U, &port1_8_pinA1_config); - - const port_pin_config_t port1_9_pinB1_config = {/* Internal pull-up/down resistor is disabled */ - kPORT_PullDisable, - /* Low internal pull resistor value is selected. */ - kPORT_LowPullResistor, - /* Fast slew rate is configured */ - kPORT_FastSlewRate, - /* Passive input filter is disabled */ - kPORT_PassiveFilterDisable, - /* Open drain output is disabled */ - kPORT_OpenDrainDisable, - /* Low drive strength is configured */ - kPORT_LowDriveStrength, - /* Pin is configured as FC4_P1 */ - kPORT_MuxAlt2, - /* Digital input enabled */ - kPORT_InputBufferEnable, - /* Digital input is not inverted */ - kPORT_InputNormal, - /* Pin Control Register fields [15:0] are not locked */ - kPORT_UnlockRegister}; - /* PORT1_9 (pin B1) is configured as FC4_P1 */ - PORT_SetPinConfig(PORT1, 9U, &port1_9_pinB1_config); - - const port_pin_config_t port0_10_pinB12_config = {/* Internal pull-up/down resistor is disabled */ - kPORT_PullDisable, - /* Low internal pull resistor value is selected. */ - kPORT_LowPullResistor, - /* Fast slew rate is configured */ - kPORT_FastSlewRate, - /* Passive input filter is disabled */ - kPORT_PassiveFilterDisable, - /* Open drain output is disabled */ - kPORT_OpenDrainDisable, - /* Low drive strength is configured */ - kPORT_LowDriveStrength, - /* Pin is configured as PIO0_10 */ - kPORT_MuxAlt0, - /* Digital input enabled */ - kPORT_InputBufferEnable, - /* Digital input is not inverted */ - kPORT_InputNormal, - /* Pin Control Register fields [15:0] are not locked */ - kPORT_UnlockRegister}; - /* PORT0_10 (pin B12) is configured as PIO0_10 */ - PORT_SetPinConfig(PORT0, 10U, &port0_10_pinB12_config); -} -/*********************************************************************************************************************** - * EOF - **********************************************************************************************************************/ diff --git a/hw/bsp/mcx/boards/frdm-mcxn947/pin_mux.h b/hw/bsp/mcx/boards/frdm-mcxn947/pin_mux.h deleted file mode 100644 index 40968c275..000000000 --- a/hw/bsp/mcx/boards/frdm-mcxn947/pin_mux.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2022 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ -/*********************************************************************************************************************** - * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file - * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. - **********************************************************************************************************************/ - -#ifndef _PIN_MUX_H_ -#define _PIN_MUX_H_ - -/*! - * @addtogroup pin_mux - * @{ - */ - -/*********************************************************************************************************************** - * API - **********************************************************************************************************************/ - -#if defined(__cplusplus) -extern "C" { -#endif - -/*! - * @brief Calls initialization functions. - * - */ -void BOARD_InitBootPins(void); - -/*! - * @brief Configures pin routing and optionally pin electrical features. - * - */ -void BOARD_InitPins(void); - -#if defined(__cplusplus) -} -#endif - -/*! - * @} - */ -#endif /* _PIN_MUX_H_ */ - -/*********************************************************************************************************************** - * EOF - **********************************************************************************************************************/ diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index d438d0715..4adc558a6 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -1729,7 +1729,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * // 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) { -#if CFG_TUD_AUDIO_ENABLE_ENCODING || CFG_TUD_AUDIO_ENABLE_DECODING || CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL +#if (CFG_TUD_AUDIO_ENABLE_EP_IN && (CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL || CFG_TUD_AUDIO_ENABLE_ENCODING)) || (CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING) uint8_t const * p_desc_parse_for_params = p_desc; #endif // From this point forward follow the EP descriptors associated to the current alternate setting interface - Open EPs if necessary diff --git a/src/class/cdc/cdc.h b/src/class/cdc/cdc.h index deec32ae4..5cbd658fe 100644 --- a/src/class/cdc/cdc.h +++ b/src/class/cdc/cdc.h @@ -136,8 +136,7 @@ typedef enum{ //--------------------------------------------------------------------+ /// Communication Interface Management Element Request Codes -typedef enum -{ +typedef enum { CDC_REQUEST_SEND_ENCAPSULATED_COMMAND = 0x00, ///< is used to issue a command in the format of the supported control protocol of the Communications Class interface CDC_REQUEST_GET_ENCAPSULATED_RESPONSE = 0x01, ///< is used to request a response in the format of the supported control protocol of the Communications Class interface. CDC_REQUEST_SET_COMM_FEATURE = 0x02, @@ -180,39 +179,38 @@ typedef enum CDC_REQUEST_GET_ATM_VC_STATISTICS = 0x53, CDC_REQUEST_MDLM_SEMANTIC_MODEL = 0x60, -}cdc_management_request_t; +} cdc_management_request_t; -enum { +typedef enum { CDC_CONTROL_LINE_STATE_DTR = 0x01, CDC_CONTROL_LINE_STATE_RTS = 0x02, -}; +} cdc_control_line_state_t; -enum { +typedef enum { CDC_LINE_CODING_STOP_BITS_1 = 0, // 1 bit CDC_LINE_CODING_STOP_BITS_1_5 = 1, // 1.5 bits CDC_LINE_CODING_STOP_BITS_2 = 2, // 2 bits -}; +} cdc_line_coding_stopbits_t; // TODO Backward compatible for typos. Maybe removed in the future release #define CDC_LINE_CONDING_STOP_BITS_1 CDC_LINE_CODING_STOP_BITS_1 #define CDC_LINE_CONDING_STOP_BITS_1_5 CDC_LINE_CODING_STOP_BITS_1_5 #define CDC_LINE_CONDING_STOP_BITS_2 CDC_LINE_CODING_STOP_BITS_2 -enum { +typedef enum { CDC_LINE_CODING_PARITY_NONE = 0, CDC_LINE_CODING_PARITY_ODD = 1, CDC_LINE_CODING_PARITY_EVEN = 2, CDC_LINE_CODING_PARITY_MARK = 3, CDC_LINE_CODING_PARITY_SPACE = 4, -}; +} cdc_line_coding_parity_t; //--------------------------------------------------------------------+ // Management Element Notification (Notification Endpoint) //--------------------------------------------------------------------+ /// 6.3 Notification Codes -typedef enum -{ +typedef enum { CDC_NOTIF_NETWORK_CONNECTION = 0x00, ///< This notification allows the device to notify the host about network connection status. CDC_NOTIF_RESPONSE_AVAILABLE = 0x01, ///< This notification allows the device to notify the hostthat a response is available. This response can be retrieved with a subsequent \ref CDC_REQUEST_GET_ENCAPSULATED_RESPONSE request. CDC_NOTIF_AUX_JACK_HOOK_STATE = 0x08, diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 2463671c6..2fb37d835 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -22,6 +22,9 @@ * THE SOFTWARE. * * This file is part of the TinyUSB stack. + * + * Contribution + * - Heiko Kuester: CH34x support */ #include "tusb_option.h" @@ -50,12 +53,18 @@ typedef struct { uint8_t bInterfaceSubClass; uint8_t bInterfaceProtocol; - uint8_t serial_drid; // Serial Driver ID - cdc_acm_capability_t acm_capability; uint8_t ep_notif; + uint8_t serial_drid; // Serial Driver ID + bool mounted; // Enumeration is complete + cdc_acm_capability_t acm_capability; - uint8_t line_state; // DTR (bit0), RTS (bit1) TU_ATTR_ALIGNED(4) cdc_line_coding_t line_coding; // Baudrate, stop bits, parity, data width + uint8_t line_state; // DTR (bit0), RTS (bit1) + + #if CFG_TUH_CDC_FTDI || CFG_TUH_CDC_CP210X || CFG_TUH_CDC_CH34X + cdc_line_coding_t requested_line_coding; + // 1 byte padding + #endif tuh_xfer_cb_t user_control_cb; @@ -69,7 +78,6 @@ typedef struct { uint8_t rx_ff_buf[CFG_TUH_CDC_TX_BUFSIZE]; CFG_TUH_MEM_ALIGN uint8_t rx_ep_buf[CFG_TUH_CDC_TX_EPSIZE]; } stream; - } cdch_interface_t; CFG_TUH_MEM_SECTION @@ -83,45 +91,57 @@ static cdch_interface_t cdch_data[CFG_TUH_CDC]; static bool acm_open(uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len); static void acm_process_config(tuh_xfer_t* xfer); +static bool acm_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +static bool acm_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, tuh_xfer_cb_t complete_cb, uintptr_t user_data); static bool acm_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data); static bool acm_set_control_line_state(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data); -static bool acm_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data); //------------- FTDI prototypes -------------// #if CFG_TUH_CDC_FTDI #include "serial/ftdi_sio.h" -static uint16_t const ftdi_vid_pid_list[][2] = {CFG_TUH_CDC_FTDI_VID_PID_LIST }; -enum { - FTDI_PID_COUNT = sizeof(ftdi_vid_pid_list) / sizeof(ftdi_vid_pid_list[0]) -}; - -// Store last request baudrate since divisor to baudrate is not easy -static uint32_t _ftdi_requested_baud; +static uint16_t const ftdi_vid_pid_list[][2] = {CFG_TUH_CDC_FTDI_VID_PID_LIST}; static bool ftdi_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len); static void ftdi_process_config(tuh_xfer_t* xfer); -static bool ftdi_sio_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data); static bool ftdi_sio_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +static bool ftdi_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +static bool ftdi_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +static bool ftdi_sio_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data); #endif //------------- CP210X prototypes -------------// #if CFG_TUH_CDC_CP210X #include "serial/cp210x.h" -static uint16_t const cp210x_vid_pid_list[][2] = {CFG_TUH_CDC_CP210X_VID_PID_LIST }; -enum { - CP210X_PID_COUNT = sizeof(cp210x_vid_pid_list) / sizeof(cp210x_vid_pid_list[0]) -}; +static uint16_t const cp210x_vid_pid_list[][2] = {CFG_TUH_CDC_CP210X_VID_PID_LIST}; static bool cp210x_open(uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len); static void cp210x_process_config(tuh_xfer_t* xfer); -static bool cp210x_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data); static bool cp210x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +static bool cp210x_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +static bool cp210x_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +static bool cp210x_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data); #endif +//------------- CH34x prototypes -------------// +#if CFG_TUH_CDC_CH34X +#include "serial/ch34x.h" + +static uint16_t const ch34x_vid_pid_list[][2] = {CFG_TUH_CDC_CH34X_VID_PID_LIST}; + +static bool ch34x_open(uint8_t daddr, tusb_desc_interface_t const* itf_desc, uint16_t max_len); +static void ch34x_process_config(tuh_xfer_t* xfer); + +static bool ch34x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +static bool ch34x_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +static bool ch34x_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +static bool ch34x_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +#endif + +//------------- Common -------------// enum { SERIAL_DRIVER_ACM = 0, @@ -132,60 +152,96 @@ enum { #if CFG_TUH_CDC_CP210X SERIAL_DRIVER_CP210X, #endif + +#if CFG_TUH_CDC_CH34X + SERIAL_DRIVER_CH34X, +#endif + + SERIAL_DRIVER_COUNT }; typedef struct { + uint16_t const (*vid_pid_list)[2]; + uint16_t const vid_pid_count; + bool (*const open)(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len); void (*const process_set_config)(tuh_xfer_t* xfer); bool (*const set_control_line_state)(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data); bool (*const set_baudrate)(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data); + bool (*const set_data_format)(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, tuh_xfer_cb_t complete_cb, uintptr_t user_data); + bool (*const set_line_coding)(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data); } cdch_serial_driver_t; // Note driver list must be in the same order as SERIAL_DRIVER enum static const cdch_serial_driver_t serial_drivers[] = { - { .process_set_config = acm_process_config, - .set_control_line_state = acm_set_control_line_state, - .set_baudrate = acm_set_baudrate + { + .vid_pid_list = NULL, + .vid_pid_count = 0, + .open = acm_open, + .process_set_config = acm_process_config, + .set_control_line_state = acm_set_control_line_state, + .set_baudrate = acm_set_baudrate, + .set_data_format = acm_set_data_format, + .set_line_coding = acm_set_line_coding }, #if CFG_TUH_CDC_FTDI - { .process_set_config = ftdi_process_config, - .set_control_line_state = ftdi_sio_set_modem_ctrl, - .set_baudrate = ftdi_sio_set_baudrate + { + .vid_pid_list = ftdi_vid_pid_list, + .vid_pid_count = TU_ARRAY_SIZE(ftdi_vid_pid_list), + .open = ftdi_open, + .process_set_config = ftdi_process_config, + .set_control_line_state = ftdi_sio_set_modem_ctrl, + .set_baudrate = ftdi_sio_set_baudrate, + .set_data_format = ftdi_set_data_format, + .set_line_coding = ftdi_set_line_coding }, #endif #if CFG_TUH_CDC_CP210X - { .process_set_config = cp210x_process_config, - .set_control_line_state = cp210x_set_modem_ctrl, - .set_baudrate = cp210x_set_baudrate + { + .vid_pid_list = cp210x_vid_pid_list, + .vid_pid_count = TU_ARRAY_SIZE(cp210x_vid_pid_list), + .open = cp210x_open, + .process_set_config = cp210x_process_config, + .set_control_line_state = cp210x_set_modem_ctrl, + .set_baudrate = cp210x_set_baudrate, + .set_data_format = cp210x_set_data_format, + .set_line_coding = cp210x_set_line_coding + }, + #endif + + #if CFG_TUH_CDC_CH34X + { + .vid_pid_list = ch34x_vid_pid_list, + .vid_pid_count = TU_ARRAY_SIZE(ch34x_vid_pid_list), + .open = ch34x_open, + .process_set_config = ch34x_process_config, + .set_control_line_state = ch34x_set_modem_ctrl, + .set_baudrate = ch34x_set_baudrate, + .set_data_format = ch34x_set_data_format, + .set_line_coding = ch34x_set_line_coding }, #endif }; -enum { - SERIAL_DRIVER_COUNT = sizeof(serial_drivers) / sizeof(serial_drivers[0]) -}; +TU_VERIFY_STATIC(TU_ARRAY_SIZE(serial_drivers) == SERIAL_DRIVER_COUNT, "Serial driver count mismatch"); //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ -static inline cdch_interface_t* get_itf(uint8_t idx) -{ +static inline cdch_interface_t* get_itf(uint8_t idx) { TU_ASSERT(idx < CFG_TUH_CDC, NULL); cdch_interface_t* p_cdc = &cdch_data[idx]; return (p_cdc->daddr != 0) ? p_cdc : NULL; } -static inline uint8_t get_idx_by_ep_addr(uint8_t daddr, uint8_t ep_addr) -{ - for(uint8_t i=0; idaddr == daddr) && - (ep_addr == p_cdc->ep_notif || ep_addr == p_cdc->stream.rx.ep_addr || ep_addr == p_cdc->stream.tx.ep_addr)) - { + (ep_addr == p_cdc->ep_notif || ep_addr == p_cdc->stream.rx.ep_addr || ep_addr == p_cdc->stream.tx.ep_addr)) { return i; } } @@ -193,14 +249,10 @@ static inline uint8_t get_idx_by_ep_addr(uint8_t daddr, uint8_t ep_addr) return TUSB_INDEX_INVALID_8; } - -static cdch_interface_t* make_new_itf(uint8_t daddr, tusb_desc_interface_t const *itf_desc) -{ - for(uint8_t i=0; idaddr = daddr; p_cdc->bInterfaceNumber = itf_desc->bInterfaceNumber; p_cdc->bInterfaceSubClass = itf_desc->bInterfaceSubClass; @@ -221,20 +273,16 @@ static void cdch_internal_control_complete(tuh_xfer_t* xfer); // APPLICATION API //--------------------------------------------------------------------+ -uint8_t tuh_cdc_itf_get_index(uint8_t daddr, uint8_t itf_num) -{ - for(uint8_t i=0; idaddr == daddr && p_cdc->bInterfaceNumber == itf_num) return i; } return TUSB_INDEX_INVALID_8; } -bool tuh_cdc_itf_get_info(uint8_t idx, tuh_itf_info_t* info) -{ +bool tuh_cdc_itf_get_info(uint8_t idx, tuh_itf_info_t* info) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc && info); @@ -256,30 +304,27 @@ bool tuh_cdc_itf_get_info(uint8_t idx, tuh_itf_info_t* info) return true; } -bool tuh_cdc_mounted(uint8_t idx) -{ +bool tuh_cdc_mounted(uint8_t idx) { cdch_interface_t* p_cdc = get_itf(idx); - return p_cdc != NULL; + TU_VERIFY(p_cdc); + return p_cdc->mounted; } -bool tuh_cdc_get_dtr(uint8_t idx) -{ +bool tuh_cdc_get_dtr(uint8_t idx) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); return (p_cdc->line_state & CDC_CONTROL_LINE_STATE_DTR) ? true : false; } -bool tuh_cdc_get_rts(uint8_t idx) -{ +bool tuh_cdc_get_rts(uint8_t idx) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); return (p_cdc->line_state & CDC_CONTROL_LINE_STATE_RTS) ? true : false; } -bool tuh_cdc_get_local_line_coding(uint8_t idx, cdc_line_coding_t* line_coding) -{ +bool tuh_cdc_get_local_line_coding(uint8_t idx, cdc_line_coding_t* line_coding) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); @@ -292,32 +337,28 @@ bool tuh_cdc_get_local_line_coding(uint8_t idx, cdc_line_coding_t* line_coding) // Write //--------------------------------------------------------------------+ -uint32_t tuh_cdc_write(uint8_t idx, void const* buffer, uint32_t bufsize) -{ +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); } -uint32_t tuh_cdc_write_flush(uint8_t idx) -{ +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); } -bool tuh_cdc_write_clear(uint8_t idx) -{ +bool tuh_cdc_write_clear(uint8_t idx) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); return tu_edpt_stream_clear(&p_cdc->stream.tx); } -uint32_t tuh_cdc_write_available(uint8_t idx) -{ +uint32_t tuh_cdc_write_available(uint8_t idx) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); @@ -328,32 +369,28 @@ uint32_t tuh_cdc_write_available(uint8_t idx) // Read //--------------------------------------------------------------------+ -uint32_t tuh_cdc_read (uint8_t idx, void* buffer, uint32_t bufsize) -{ +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); } -uint32_t tuh_cdc_read_available(uint8_t idx) -{ +uint32_t tuh_cdc_read_available(uint8_t idx) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); return tu_edpt_stream_read_available(&p_cdc->stream.rx); } -bool tuh_cdc_peek(uint8_t idx, uint8_t* ch) -{ +bool tuh_cdc_peek(uint8_t idx, uint8_t* ch) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); return tu_edpt_stream_peek(&p_cdc->stream.rx, ch); } -bool tuh_cdc_read_clear (uint8_t idx) -{ +bool tuh_cdc_read_clear (uint8_t idx) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); @@ -366,28 +403,25 @@ bool tuh_cdc_read_clear (uint8_t idx) // Control Endpoint API //--------------------------------------------------------------------+ -// internal control complete to update state such as line state, encoding -static void cdch_internal_control_complete(tuh_xfer_t* xfer) -{ - uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); +static void process_internal_control_complete(tuh_xfer_t* xfer, uint8_t itf_num) { uint8_t idx = tuh_cdc_itf_get_index(xfer->daddr, itf_num); cdch_interface_t* p_cdc = get_itf(idx); TU_ASSERT(p_cdc, ); + uint16_t const value = tu_le16toh(xfer->setup->wValue); - if (xfer->result == XFER_RESULT_SUCCESS) - { + if (xfer->result == XFER_RESULT_SUCCESS) { switch (p_cdc->serial_drid) { case SERIAL_DRIVER_ACM: switch (xfer->setup->bRequest) { case CDC_REQUEST_SET_CONTROL_LINE_STATE: - p_cdc->line_state = (uint8_t) tu_le16toh(xfer->setup->wValue); + p_cdc->line_state = (uint8_t) value; break; case CDC_REQUEST_SET_LINE_CODING: { uint16_t const len = tu_min16(sizeof(cdc_line_coding_t), tu_le16toh(xfer->setup->wLength)); memcpy(&p_cdc->line_coding, xfer->buffer, len); - } break; + } default: break; } @@ -397,12 +431,11 @@ static void cdch_internal_control_complete(tuh_xfer_t* xfer) case SERIAL_DRIVER_FTDI: switch (xfer->setup->bRequest) { case FTDI_SIO_MODEM_CTRL: - p_cdc->line_state = (uint8_t) (tu_le16toh(xfer->setup->wValue) & 0x00ff); + p_cdc->line_state = (uint8_t) value; break; case FTDI_SIO_SET_BAUD_RATE: - // convert from divisor to baudrate is not supported - p_cdc->line_coding.bit_rate = _ftdi_requested_baud; + p_cdc->line_coding.bit_rate = p_cdc->requested_line_coding.bit_rate; break; default: break; @@ -414,15 +447,61 @@ static void cdch_internal_control_complete(tuh_xfer_t* xfer) case SERIAL_DRIVER_CP210X: switch(xfer->setup->bRequest) { case CP210X_SET_MHS: - p_cdc->line_state = (uint8_t) (tu_le16toh(xfer->setup->wValue) & 0x00ff); + p_cdc->line_state = (uint8_t) value; break; case CP210X_SET_BAUDRATE: { uint32_t baudrate; memcpy(&baudrate, xfer->buffer, sizeof(uint32_t)); p_cdc->line_coding.bit_rate = tu_le32toh(baudrate); - } break; + } + + default: break; + } + break; + #endif + + #if CFG_TUH_CDC_CH34X + case SERIAL_DRIVER_CH34X: + switch (xfer->setup->bRequest) { + case CH34X_REQ_WRITE_REG: + // register write request + switch (value) { + case CH34X_REG16_DIVISOR_PRESCALER: + // baudrate + p_cdc->line_coding.bit_rate = p_cdc->requested_line_coding.bit_rate; + break; + + case CH32X_REG16_LCR2_LCR: + // data format + p_cdc->line_coding.stop_bits = p_cdc->requested_line_coding.stop_bits; + p_cdc->line_coding.parity = p_cdc->requested_line_coding.parity; + p_cdc->line_coding.data_bits = p_cdc->requested_line_coding.data_bits; + break; + + default: break; + } + break; + + case CH34X_REQ_MODEM_CTRL: { + // set modem controls RTS/DTR request. Note: signals are inverted + uint16_t const modem_signal = ~value; + if (modem_signal & CH34X_BIT_RTS) { + p_cdc->line_state |= CDC_CONTROL_LINE_STATE_RTS; + } else { + p_cdc->line_state &= (uint8_t) ~CDC_CONTROL_LINE_STATE_RTS; + } + + if (modem_signal & CH34X_BIT_DTR) { + p_cdc->line_state |= CDC_CONTROL_LINE_STATE_DTR; + } else { + p_cdc->line_state &= (uint8_t) ~CDC_CONTROL_LINE_STATE_DTR; + } + break; + } + + default: break; } break; #endif @@ -437,14 +516,20 @@ static void cdch_internal_control_complete(tuh_xfer_t* xfer) } } +// internal control complete to update state such as line state, encoding +static void cdch_internal_control_complete(tuh_xfer_t* xfer) { + uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); + process_internal_control_complete(xfer, itf_num); +} + bool tuh_cdc_set_control_line_state(uint8_t idx, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc && p_cdc->serial_drid < SERIAL_DRIVER_COUNT); cdch_serial_driver_t const* driver = &serial_drivers[p_cdc->serial_drid]; - if ( complete_cb ) { + if (complete_cb) { return driver->set_control_line_state(p_cdc, line_state, complete_cb, user_data); - }else { + } else { // blocking xfer_result_t result = XFER_RESULT_INVALID; bool ret = driver->set_control_line_state(p_cdc, line_state, complete_cb, (uintptr_t) &result); @@ -455,7 +540,6 @@ bool tuh_cdc_set_control_line_state(uint8_t idx, uint16_t line_state, tuh_xfer_c } TU_VERIFY(ret && result == XFER_RESULT_SUCCESS); - p_cdc->line_state = (uint8_t) line_state; return true; } @@ -466,9 +550,9 @@ bool tuh_cdc_set_baudrate(uint8_t idx, uint32_t baudrate, tuh_xfer_cb_t complete TU_VERIFY(p_cdc && p_cdc->serial_drid < SERIAL_DRIVER_COUNT); cdch_serial_driver_t const* driver = &serial_drivers[p_cdc->serial_drid]; - if ( complete_cb ) { + if (complete_cb) { return driver->set_baudrate(p_cdc, baudrate, complete_cb, user_data); - }else { + } else { // blocking xfer_result_t result = XFER_RESULT_INVALID; bool ret = driver->set_baudrate(p_cdc, baudrate, complete_cb, (uintptr_t) &result); @@ -479,25 +563,23 @@ bool tuh_cdc_set_baudrate(uint8_t idx, uint32_t baudrate, tuh_xfer_cb_t complete } TU_VERIFY(ret && result == XFER_RESULT_SUCCESS); - p_cdc->line_coding.bit_rate = baudrate; return true; } } -bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ +bool tuh_cdc_set_data_format(uint8_t idx, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { cdch_interface_t* p_cdc = get_itf(idx); - // only ACM support this set line coding request - TU_VERIFY(p_cdc && p_cdc->serial_drid == SERIAL_DRIVER_ACM); - TU_VERIFY(p_cdc->acm_capability.support_line_request); + TU_VERIFY(p_cdc && p_cdc->serial_drid < SERIAL_DRIVER_COUNT); + cdch_serial_driver_t const* driver = &serial_drivers[p_cdc->serial_drid]; - if ( complete_cb ) { - return acm_set_line_coding(p_cdc, line_coding, complete_cb, user_data); - }else { + if (complete_cb) { + return driver->set_data_format(p_cdc, stop_bits, parity, data_bits, complete_cb, user_data); + } else { // blocking xfer_result_t result = XFER_RESULT_INVALID; - bool ret = acm_set_line_coding(p_cdc, line_coding, complete_cb, (uintptr_t) &result); + bool ret = driver->set_data_format(p_cdc, stop_bits, parity, data_bits, complete_cb, (uintptr_t) &result); if (user_data) { // user_data is not NULL, return result via user_data @@ -505,7 +587,31 @@ bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding, } TU_VERIFY(ret && result == XFER_RESULT_SUCCESS); + p_cdc->line_coding.stop_bits = stop_bits; + p_cdc->line_coding.parity = parity; + p_cdc->line_coding.data_bits = data_bits; + return true; + } +} +bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + cdch_interface_t* p_cdc = get_itf(idx); + TU_VERIFY(p_cdc && p_cdc->serial_drid < SERIAL_DRIVER_COUNT); + cdch_serial_driver_t const* driver = &serial_drivers[p_cdc->serial_drid]; + + if ( complete_cb ) { + return driver->set_line_coding(p_cdc, line_coding, complete_cb, user_data); + } else { + // blocking + xfer_result_t result = XFER_RESULT_INVALID; + bool ret = driver->set_line_coding(p_cdc, line_coding, complete_cb, (uintptr_t) &result); + + if (user_data) { + // user_data is not NULL, return result via user_data + *((xfer_result_t*) user_data) = result; + } + + TU_VERIFY(ret && result == XFER_RESULT_SUCCESS); p_cdc->line_coding = *line_coding; return true; } @@ -515,39 +621,34 @@ bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding, // CLASS-USBH API //--------------------------------------------------------------------+ -void cdch_init(void) -{ +void cdch_init(void) { tu_memclr(cdch_data, sizeof(cdch_data)); - for(size_t i=0; istream.tx, true, true, false, - p_cdc->stream.tx_ff_buf, CFG_TUH_CDC_TX_BUFSIZE, - p_cdc->stream.tx_ep_buf, CFG_TUH_CDC_TX_EPSIZE); + p_cdc->stream.tx_ff_buf, CFG_TUH_CDC_TX_BUFSIZE, + p_cdc->stream.tx_ep_buf, CFG_TUH_CDC_TX_EPSIZE); tu_edpt_stream_init(&p_cdc->stream.rx, true, false, false, - p_cdc->stream.rx_ff_buf, CFG_TUH_CDC_RX_BUFSIZE, - p_cdc->stream.rx_ep_buf, CFG_TUH_CDC_RX_EPSIZE); + p_cdc->stream.rx_ff_buf, CFG_TUH_CDC_RX_BUFSIZE, + p_cdc->stream.rx_ep_buf, CFG_TUH_CDC_RX_EPSIZE); } } -void cdch_close(uint8_t daddr) -{ - for(uint8_t idx=0; idxdaddr == daddr) - { + if (p_cdc->daddr == daddr) { TU_LOG_DRV(" CDCh close addr = %u index = %u\r\n", daddr, idx); // Invoke application callback if (tuh_cdc_umount_cb) tuh_cdc_umount_cb(idx); - //tu_memclr(p_cdc, sizeof(cdch_interface_t)); p_cdc->daddr = 0; p_cdc->bInterfaceNumber = 0; + p_cdc->mounted = false; tu_edpt_stream_close(&p_cdc->stream.tx); tu_edpt_stream_close(&p_cdc->stream.rx); } @@ -571,16 +672,11 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t // - xferred_bytes is multiple of EP Packet size and not zero tu_edpt_stream_write_zlp_if_needed(&p_cdc->stream.tx, xferred_bytes); } - } - else if ( ep_addr == p_cdc->stream.rx.ep_addr ) { + } else if ( ep_addr == p_cdc->stream.rx.ep_addr ) { #if CFG_TUH_CDC_FTDI if (p_cdc->serial_drid == SERIAL_DRIVER_FTDI) { // FTDI reserve 2 bytes for status - // FTDI status -// uint8_t status[2] = { -// p_cdc->stream.rx.ep_buf[0], -// p_cdc->stream.rx.ep_buf[1] -// }; + // uint8_t status[2] = {p_cdc->stream.rx.ep_buf[0], p_cdc->stream.rx.ep_buf[1]}; tu_edpt_stream_read_xfer_complete_offset(&p_cdc->stream.rx, xferred_bytes, 2); }else #endif @@ -606,20 +702,15 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t // Enumeration //--------------------------------------------------------------------+ -static bool open_ep_stream_pair(cdch_interface_t* p_cdc, tusb_desc_endpoint_t const *desc_ep) -{ - for(size_t i=0; i<2; i++) - { +static bool open_ep_stream_pair(cdch_interface_t* p_cdc, tusb_desc_endpoint_t const* desc_ep) { + for (size_t i = 0; i < 2; i++) { TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && - TUSB_XFER_BULK == desc_ep->bmAttributes.xfer); - + TUSB_XFER_BULK == desc_ep->bmAttributes.xfer); TU_ASSERT(tuh_edpt_open(p_cdc->daddr, desc_ep)); - if ( tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN ) - { + if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { tu_edpt_stream_open(&p_cdc->stream.rx, p_cdc->daddr, desc_ep); - }else - { + } else { tu_edpt_stream_open(&p_cdc->stream.tx, p_cdc->daddr, desc_ep); } @@ -629,45 +720,36 @@ static bool open_ep_stream_pair(cdch_interface_t* p_cdc, tusb_desc_endpoint_t co return true; } -bool cdch_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len) -{ +bool cdch_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len) { (void) rhport; - // Only support ACM subclass + // For CDC: only support ACM subclass // Note: Protocol 0xFF can be RNDIS device - if ( TUSB_CLASS_CDC == itf_desc->bInterfaceClass && - CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass) - { + if (TUSB_CLASS_CDC == itf_desc->bInterfaceClass && + CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass) { return acm_open(daddr, itf_desc, max_len); } - #if CFG_TUH_CDC_FTDI || CFG_TUH_CDC_CP210X - else if ( TUSB_CLASS_VENDOR_SPECIFIC == itf_desc->bInterfaceClass ) - { + else if (SERIAL_DRIVER_COUNT > 1 && + TUSB_CLASS_VENDOR_SPECIFIC == itf_desc->bInterfaceClass) { uint16_t vid, pid; TU_VERIFY(tuh_vid_pid_get(daddr, &vid, &pid)); - #if CFG_TUH_CDC_FTDI - for (size_t i = 0; i < FTDI_PID_COUNT; i++) { - if (ftdi_vid_pid_list[i][0] == vid && ftdi_vid_pid_list[i][1] == pid) { - return ftdi_open(daddr, itf_desc, max_len); + for (size_t dr = 1; dr < SERIAL_DRIVER_COUNT; dr++) { + cdch_serial_driver_t const* driver = &serial_drivers[dr]; + for (size_t i = 0; i < driver->vid_pid_count; i++) { + if (driver->vid_pid_list[i][0] == vid && driver->vid_pid_list[i][1] == pid) { + return driver->open(daddr, itf_desc, max_len); + } } } - #endif - - #if CFG_TUH_CDC_CP210X - for (size_t i = 0; i < CP210X_PID_COUNT; i++) { - if (cp210x_vid_pid_list[i][0] == vid && cp210x_vid_pid_list[i][1] == pid) { - return cp210x_open(daddr, itf_desc, max_len); - } - } - #endif } - #endif return false; } static void set_config_complete(cdch_interface_t * p_cdc, uint8_t idx, uint8_t itf_num) { + TU_LOG_DRV("CDCh Set Configure complete\r\n"); + p_cdc->mounted = true; if (tuh_cdc_mount_cb) tuh_cdc_mount_cb(idx); // Prepare for incoming data @@ -677,9 +759,7 @@ static void set_config_complete(cdch_interface_t * p_cdc, uint8_t idx, uint8_t i usbh_driver_set_config_complete(p_cdc->daddr, itf_num); } - -bool cdch_set_config(uint8_t daddr, uint8_t itf_num) -{ +bool cdch_set_config(uint8_t daddr, uint8_t itf_num) { tusb_control_request_t request; request.wIndex = tu_htole16((uint16_t) itf_num); @@ -708,94 +788,84 @@ enum { CONFIG_ACM_COMPLETE, }; -static bool acm_open(uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len) -{ - uint8_t const * p_desc_end = ((uint8_t const*) itf_desc) + max_len; +static bool acm_open(uint8_t daddr, tusb_desc_interface_t const* itf_desc, uint16_t max_len) { + uint8_t const* p_desc_end = ((uint8_t const*) itf_desc) + max_len; - cdch_interface_t * p_cdc = make_new_itf(daddr, itf_desc); + cdch_interface_t* p_cdc = make_new_itf(daddr, itf_desc); TU_VERIFY(p_cdc); - p_cdc->serial_drid = SERIAL_DRIVER_ACM; //------------- Control Interface -------------// - uint8_t const * p_desc = tu_desc_next(itf_desc); + uint8_t const* p_desc = tu_desc_next(itf_desc); // Communication Functional Descriptors - while( (p_desc < p_desc_end) && (TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc)) ) - { - if ( CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT == cdc_functional_desc_typeof(p_desc) ) - { + while ((p_desc < p_desc_end) && (TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc))) { + if (CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT == cdc_functional_desc_typeof(p_desc)) { // save ACM bmCapabilities - p_cdc->acm_capability = ((cdc_desc_func_acm_t const *) p_desc)->bmCapabilities; + p_cdc->acm_capability = ((cdc_desc_func_acm_t const*) p_desc)->bmCapabilities; } p_desc = tu_desc_next(p_desc); } // Open notification endpoint of control interface if any - if (itf_desc->bNumEndpoints == 1) - { + if (itf_desc->bNumEndpoints == 1) { TU_ASSERT(TUSB_DESC_ENDPOINT == tu_desc_type(p_desc)); - 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( tuh_edpt_open(daddr, desc_ep) ); + TU_ASSERT(tuh_edpt_open(daddr, desc_ep)); p_cdc->ep_notif = desc_ep->bEndpointAddress; 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 p_desc = tu_desc_next(p_desc); // data endpoints expected to be in pairs - TU_ASSERT(open_ep_stream_pair(p_cdc, (tusb_desc_endpoint_t const *) p_desc)); + TU_ASSERT(open_ep_stream_pair(p_cdc, (tusb_desc_endpoint_t const*) p_desc)); } return true; } -static void acm_process_config(tuh_xfer_t* xfer) -{ +static void acm_process_config(tuh_xfer_t* xfer) { uintptr_t const state = xfer->user_data; uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); uint8_t const idx = tuh_cdc_itf_get_index(xfer->daddr, itf_num); - cdch_interface_t * p_cdc = get_itf(idx); - TU_ASSERT(p_cdc, ); + cdch_interface_t* p_cdc = get_itf(idx); + TU_ASSERT(p_cdc,); - switch(state) - { + switch (state) { case CONFIG_ACM_SET_CONTROL_LINE_STATE: #if CFG_TUH_CDC_LINE_CONTROL_ON_ENUM - if (p_cdc->acm_capability.support_line_request) - { - TU_ASSERT(acm_set_control_line_state(p_cdc, CFG_TUH_CDC_LINE_CONTROL_ON_ENUM, acm_process_config, - CONFIG_ACM_SET_LINE_CODING), ); + if (p_cdc->acm_capability.support_line_request) { + TU_ASSERT(acm_set_control_line_state(p_cdc, CFG_TUH_CDC_LINE_CONTROL_ON_ENUM, acm_process_config, CONFIG_ACM_SET_LINE_CODING),); break; } - #endif + #endif TU_ATTR_FALLTHROUGH; case CONFIG_ACM_SET_LINE_CODING: - #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM - if (p_cdc->acm_capability.support_line_request) - { + #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM + if (p_cdc->acm_capability.support_line_request) { cdc_line_coding_t line_coding = CFG_TUH_CDC_LINE_CODING_ON_ENUM; - TU_ASSERT(acm_set_line_coding(p_cdc, &line_coding, acm_process_config, CONFIG_ACM_COMPLETE), ); + TU_ASSERT(acm_set_line_coding(p_cdc, &line_coding, acm_process_config, CONFIG_ACM_COMPLETE),); break; } - #endif + #endif TU_ATTR_FALLTHROUGH; case CONFIG_ACM_COMPLETE: // itf_num+1 to account for data interface as well - set_config_complete(p_cdc, idx, itf_num+1); + set_config_complete(p_cdc, idx, itf_num + 1); break; - default: break; + default: + break; } } @@ -863,6 +933,19 @@ static bool acm_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const return true; } +static bool acm_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + TU_LOG_DRV("CDC ACM Set Data Format\r\n"); + + cdc_line_coding_t line_coding; + line_coding.bit_rate = p_cdc->line_coding.bit_rate; + line_coding.stop_bits = stop_bits; + line_coding.parity = parity; + line_coding.data_bits = data_bits; + + return acm_set_line_coding(p_cdc, &line_coding, complete_cb, user_data); +} + static bool acm_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { TU_VERIFY(p_cdc->acm_capability.support_line_request); cdc_line_coding_t line_coding = p_cdc->line_coding; @@ -892,7 +975,6 @@ static bool ftdi_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint TU_VERIFY(p_cdc); TU_LOG_DRV("FTDI opened\r\n"); - p_cdc->serial_drid = SERIAL_DRIVER_FTDI; // endpoint pair @@ -928,13 +1010,32 @@ static bool ftdi_sio_set_request(cdch_interface_t* p_cdc, uint8_t command, uint1 return tuh_control_xfer(&xfer); } -static bool ftdi_sio_reset(cdch_interface_t* p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ +static bool ftdi_sio_reset(cdch_interface_t* p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return ftdi_sio_set_request(p_cdc, FTDI_SIO_RESET, FTDI_SIO_RESET_SIO, complete_cb, user_data); } -static bool ftdi_sio_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ +static bool ftdi_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + (void) p_cdc; + (void) stop_bits; + (void) parity; + (void) data_bits; + (void) complete_cb; + (void) user_data; + // TODO not implemented yet + return false; +} + +static bool ftdi_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + (void) p_cdc; + (void) line_coding; + (void) complete_cb; + (void) user_data; + // TODO not implemented yet + return false; +} + +static bool ftdi_sio_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { TU_LOG_DRV("CDC FTDI Set Control Line State\r\n"); p_cdc->user_control_cb = complete_cb; TU_ASSERT(ftdi_sio_set_request(p_cdc, FTDI_SIO_MODEM_CTRL, 0x0300 | line_state, @@ -942,8 +1043,7 @@ static bool ftdi_sio_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state return true; } -static uint32_t ftdi_232bm_baud_base_to_divisor(uint32_t baud, uint32_t base) -{ +static uint32_t ftdi_232bm_baud_base_to_divisor(uint32_t baud, uint32_t base) { const uint8_t divfrac[8] = { 0, 3, 2, 4, 1, 5, 6, 7 }; uint32_t divisor; @@ -963,18 +1063,16 @@ static uint32_t ftdi_232bm_baud_base_to_divisor(uint32_t baud, uint32_t base) return divisor; } -static uint32_t ftdi_232bm_baud_to_divisor(uint32_t baud) -{ +static uint32_t ftdi_232bm_baud_to_divisor(uint32_t baud) { return ftdi_232bm_baud_base_to_divisor(baud, 48000000u); } -static bool ftdi_sio_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ +static bool ftdi_sio_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { uint16_t const divisor = (uint16_t) ftdi_232bm_baud_to_divisor(baudrate); TU_LOG_DRV("CDC FTDI Set BaudRate = %lu, divisor = 0x%04x\r\n", baudrate, divisor); p_cdc->user_control_cb = complete_cb; - _ftdi_requested_baud = baudrate; + p_cdc->requested_line_coding.bit_rate = baudrate; TU_ASSERT(ftdi_sio_set_request(p_cdc, FTDI_SIO_SET_BAUD_RATE, divisor, complete_cb ? cdch_internal_control_complete : NULL, user_data)); @@ -996,8 +1094,7 @@ static void ftdi_process_config(tuh_xfer_t* xfer) { case CONFIG_FTDI_MODEM_CTRL: #if CFG_TUH_CDC_LINE_CONTROL_ON_ENUM - TU_ASSERT( - ftdi_sio_set_modem_ctrl(p_cdc, CFG_TUH_CDC_LINE_CONTROL_ON_ENUM, ftdi_process_config, CONFIG_FTDI_SET_BAUDRATE),); + TU_ASSERT(ftdi_sio_set_modem_ctrl(p_cdc, CFG_TUH_CDC_LINE_CONTROL_ON_ENUM, ftdi_process_config, CONFIG_FTDI_SET_BAUDRATE),); break; #else TU_ATTR_FALLTHROUGH; @@ -1105,6 +1202,15 @@ static bool cp210x_ifc_enable(cdch_interface_t* p_cdc, uint16_t enabled, tuh_xfe return cp210x_set_request(p_cdc, CP210X_IFC_ENABLE, enabled, NULL, 0, complete_cb, user_data); } +static bool cp210x_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + // TODO implement later + (void) p_cdc; + (void) line_coding; + (void) complete_cb; + (void) user_data; + return false; +} + static bool cp210x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { TU_LOG_DRV("CDC CP210x Set BaudRate = %lu\r\n", baudrate); uint32_t baud_le = tu_htole32(baudrate); @@ -1113,8 +1219,19 @@ static bool cp210x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_ complete_cb ? cdch_internal_control_complete : NULL, user_data); } -static bool cp210x_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ +static bool cp210x_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + (void) p_cdc; + (void) stop_bits; + (void) parity; + (void) data_bits; + (void) complete_cb; + (void) user_data; + // TODO not implemented yet + return false; +} + +static bool cp210x_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { TU_LOG_DRV("CDC CP210x Set Control Line State\r\n"); p_cdc->user_control_cb = complete_cb; return cp210x_set_request(p_cdc, CP210X_SET_MHS, 0x0300 | line_state, NULL, 0, @@ -1154,8 +1271,7 @@ static void cp210x_process_config(tuh_xfer_t* xfer) { case CONFIG_CP210X_SET_DTR_RTS: #if CFG_TUH_CDC_LINE_CONTROL_ON_ENUM - TU_ASSERT( - cp210x_set_modem_ctrl(p_cdc, CFG_TUH_CDC_LINE_CONTROL_ON_ENUM, cp210x_process_config, CONFIG_CP210X_COMPLETE),); + TU_ASSERT(cp210x_set_modem_ctrl(p_cdc, CFG_TUH_CDC_LINE_CONTROL_ON_ENUM, cp210x_process_config, CONFIG_CP210X_COMPLETE),); break; #else TU_ATTR_FALLTHROUGH; @@ -1171,4 +1287,374 @@ static void cp210x_process_config(tuh_xfer_t* xfer) { #endif +//--------------------------------------------------------------------+ +// CH34x (CH340 & CH341) +//--------------------------------------------------------------------+ + +#if CFG_TUH_CDC_CH34X + +static uint8_t ch34x_get_lcr(uint8_t stop_bits, uint8_t parity, uint8_t data_bits); +static uint16_t ch34x_get_divisor_prescaler(uint32_t baval); + +//------------- control request -------------// + +static bool ch34x_set_request(cdch_interface_t* p_cdc, uint8_t direction, uint8_t request, uint16_t value, + uint16_t index, uint8_t* buffer, uint16_t length, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + tusb_control_request_t const request_setup = { + .bmRequestType_bit = { + .recipient = TUSB_REQ_RCPT_DEVICE, + .type = TUSB_REQ_TYPE_VENDOR, + .direction = direction & 0x01u + }, + .bRequest = request, + .wValue = tu_htole16 (value), + .wIndex = tu_htole16 (index), + .wLength = tu_htole16 (length) + }; + + // use usbh enum buf since application variable does not live long enough + uint8_t* enum_buf = NULL; + + if (buffer && length > 0) { + enum_buf = usbh_get_enum_buf(); + if (direction == TUSB_DIR_OUT) { + tu_memcpy_s(enum_buf, CFG_TUH_ENUMERATION_BUFSIZE, buffer, length); + } + } + + tuh_xfer_t xfer = { + .daddr = p_cdc->daddr, + .ep_addr = 0, + .setup = &request_setup, + .buffer = enum_buf, + .complete_cb = complete_cb, + .user_data = user_data + }; + + return tuh_control_xfer(&xfer); +} + +static inline bool ch34x_control_out(cdch_interface_t* p_cdc, uint8_t request, uint16_t value, uint16_t index, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + return ch34x_set_request(p_cdc, TUSB_DIR_OUT, request, value, index, NULL, 0, complete_cb, user_data); +} + +static inline bool ch34x_control_in(cdch_interface_t* p_cdc, uint8_t request, uint16_t value, uint16_t index, + uint8_t* buffer, uint16_t buffersize, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + return ch34x_set_request(p_cdc, TUSB_DIR_IN, request, value, index, buffer, buffersize, + complete_cb, user_data); +} + +static inline bool ch34x_write_reg(cdch_interface_t* p_cdc, uint16_t reg, uint16_t reg_value, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + return ch34x_control_out(p_cdc, CH34X_REQ_WRITE_REG, reg, reg_value, complete_cb, user_data); +} + +//static bool ch34x_read_reg_request ( cdch_interface_t* p_cdc, uint16_t reg, +// uint8_t *buffer, uint16_t buffersize, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) +//{ +// return ch34x_control_in ( p_cdc, CH34X_REQ_READ_REG, reg, 0, buffer, buffersize, complete_cb, user_data ); +//} + +static bool ch34x_write_reg_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + uint16_t const div_ps = ch34x_get_divisor_prescaler(baudrate); + TU_VERIFY(div_ps); + TU_ASSERT(ch34x_write_reg(p_cdc, CH34X_REG16_DIVISOR_PRESCALER, div_ps, + complete_cb, user_data)); + return true; +} + +//------------- Driver API -------------// + +// internal control complete to update state such as line state, encoding +static void ch34x_control_complete(tuh_xfer_t* xfer) { + // CH34x only has 1 interface and use wIndex as payload and not for bInterfaceNumber + process_internal_control_complete(xfer, 0); +} + +static bool ch34x_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + p_cdc->requested_line_coding.stop_bits = stop_bits; + p_cdc->requested_line_coding.parity = parity; + p_cdc->requested_line_coding.data_bits = data_bits; + + uint8_t const lcr = ch34x_get_lcr(stop_bits, parity, data_bits); + TU_VERIFY(lcr); + TU_ASSERT (ch34x_control_out(p_cdc, CH34X_REQ_WRITE_REG, CH32X_REG16_LCR2_LCR, lcr, + complete_cb ? ch34x_control_complete : NULL, user_data)); + return true; +} + +static bool ch34x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + p_cdc->requested_line_coding.bit_rate = baudrate; + p_cdc->user_control_cb = complete_cb; + TU_ASSERT(ch34x_write_reg_baudrate(p_cdc, baudrate, + complete_cb ? ch34x_control_complete : NULL, user_data)); + return true; +} + +static void ch34x_set_line_coding_stage1_complete(tuh_xfer_t* xfer) { + // CH34x only has 1 interface and use wIndex as payload and not for bInterfaceNumber + uint8_t const itf_num = 0; + uint8_t const idx = tuh_cdc_itf_get_index(xfer->daddr, itf_num); + cdch_interface_t* p_cdc = get_itf(idx); + TU_ASSERT(p_cdc, ); + + if (xfer->result == XFER_RESULT_SUCCESS) { + // stage 1 success, continue to stage 2 + p_cdc->line_coding.bit_rate = p_cdc->requested_line_coding.bit_rate; + TU_ASSERT(ch34x_set_data_format(p_cdc, p_cdc->requested_line_coding.stop_bits, p_cdc->requested_line_coding.parity, + p_cdc->requested_line_coding.data_bits, ch34x_control_complete, xfer->user_data), ); + } else { + // stage 1 failed, notify user + xfer->complete_cb = p_cdc->user_control_cb; + if (xfer->complete_cb) { + xfer->complete_cb(xfer); + } + } +} + +// 2 stages: set baudrate (stage1) + set data format (stage2) +static bool ch34x_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + p_cdc->requested_line_coding = *line_coding; + p_cdc->user_control_cb = complete_cb; + + if (complete_cb) { + // stage 1 set baudrate + TU_ASSERT(ch34x_write_reg_baudrate(p_cdc, line_coding->bit_rate, + ch34x_set_line_coding_stage1_complete, user_data)); + } else { + // sync call + xfer_result_t result; + + // stage 1 set baudrate + TU_ASSERT(ch34x_write_reg_baudrate(p_cdc, line_coding->bit_rate, NULL, (uintptr_t) &result)); + TU_VERIFY(result == XFER_RESULT_SUCCESS); + p_cdc->line_coding.bit_rate = line_coding->bit_rate; + + // stage 2 set data format + TU_ASSERT(ch34x_set_data_format(p_cdc, line_coding->stop_bits, line_coding->parity, line_coding->data_bits, + NULL, (uintptr_t) &result)); + TU_VERIFY(result == XFER_RESULT_SUCCESS); + p_cdc->line_coding.stop_bits = line_coding->stop_bits; + p_cdc->line_coding.parity = line_coding->parity; + p_cdc->line_coding.data_bits = line_coding->data_bits; + + // update transfer result, user_data is expected to point to xfer_result_t + if (user_data) { + *((xfer_result_t*) user_data) = result; + } + } + + return true; +} + +static bool ch34x_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + uint8_t control = 0; + if (line_state & CDC_CONTROL_LINE_STATE_RTS) { + control |= CH34X_BIT_RTS; + } + if (line_state & CDC_CONTROL_LINE_STATE_DTR) { + control |= CH34X_BIT_DTR; + } + + // CH34x signals are inverted + control = ~control; + + p_cdc->user_control_cb = complete_cb; + TU_ASSERT (ch34x_control_out(p_cdc, CH34X_REQ_MODEM_CTRL, control, 0, + complete_cb ? ch34x_control_complete : NULL, user_data)); + return true; +} + +//------------- Enumeration -------------// +enum { + CONFIG_CH34X_READ_VERSION = 0, + CONFIG_CH34X_SERIAL_INIT, + CONFIG_CH34X_SPECIAL_REG_WRITE, + CONFIG_CH34X_FLOW_CONTROL, + CONFIG_CH34X_MODEM_CONTROL, + CONFIG_CH34X_COMPLETE +}; + +static bool ch34x_open(uint8_t daddr, tusb_desc_interface_t const* itf_desc, uint16_t max_len) { + // CH34x Interface includes 1 vendor interface + 2 bulk + 1 interrupt endpoints + TU_VERIFY (itf_desc->bNumEndpoints == 3); + TU_VERIFY (sizeof(tusb_desc_interface_t) + 3 * sizeof(tusb_desc_endpoint_t) <= max_len); + + cdch_interface_t* p_cdc = make_new_itf(daddr, itf_desc); + TU_VERIFY (p_cdc); + + TU_LOG_DRV ("CH34x opened\r\n"); + p_cdc->serial_drid = SERIAL_DRIVER_CH34X; + + tusb_desc_endpoint_t const* desc_ep = (tusb_desc_endpoint_t const*) tu_desc_next(itf_desc); + + // data endpoints expected to be in pairs + TU_ASSERT(open_ep_stream_pair(p_cdc, desc_ep)); + desc_ep += 2; + + // Interrupt endpoint: not used for now + TU_ASSERT(TUSB_DESC_ENDPOINT == tu_desc_type(desc_ep) && + TUSB_XFER_INTERRUPT == desc_ep->bmAttributes.xfer); + TU_ASSERT(tuh_edpt_open(daddr, desc_ep)); + p_cdc->ep_notif = desc_ep->bEndpointAddress; + + return true; +} + +static void ch34x_process_config(tuh_xfer_t* xfer) { + // CH34x only has 1 interface and use wIndex as payload and not for bInterfaceNumber + uint8_t const itf_num = 0; + uint8_t const idx = tuh_cdc_itf_get_index(xfer->daddr, itf_num); + cdch_interface_t* p_cdc = get_itf(idx); + uintptr_t const state = xfer->user_data; + uint8_t buffer[2]; // TODO remove + TU_ASSERT (p_cdc,); + TU_ASSERT (xfer->result == XFER_RESULT_SUCCESS,); + + switch (state) { + case CONFIG_CH34X_READ_VERSION: + TU_LOG_DRV("[%u] CDCh CH34x attempt to read Chip Version\r\n", p_cdc->daddr); + TU_ASSERT (ch34x_control_in(p_cdc, CH34X_REQ_READ_VERSION, 0, 0, buffer, 2, ch34x_process_config, CONFIG_CH34X_SERIAL_INIT),); + break; + + case CONFIG_CH34X_SERIAL_INIT: { + // handle version read data, set CH34x line coding (incl. baudrate) + uint8_t const version = xfer->buffer[0]; + TU_LOG_DRV("[%u] CDCh CH34x Chip Version = %02x\r\n", p_cdc->daddr, version); + // only versions >= 0x30 are tested, below 0x30 seems having other programming, see drivers from WCH vendor, Linux kernel and FreeBSD + TU_ASSERT (version >= 0x30,); + // init CH34x with line coding + cdc_line_coding_t const line_coding = CFG_TUH_CDC_LINE_CODING_ON_ENUM_CH34X; + uint16_t const div_ps = ch34x_get_divisor_prescaler(line_coding.bit_rate); + TU_ASSERT(div_ps, ); + uint8_t const lcr = ch34x_get_lcr(line_coding.stop_bits, line_coding.parity, line_coding.data_bits); + TU_ASSERT(lcr, ); + TU_ASSERT (ch34x_control_out(p_cdc, CH34X_REQ_SERIAL_INIT, tu_u16(lcr, 0x9c), div_ps, + ch34x_process_config, CONFIG_CH34X_SPECIAL_REG_WRITE),); + break; + } + + case CONFIG_CH34X_SPECIAL_REG_WRITE: + // overtake line coding and do special reg write, purpose unknown, overtaken from WCH driver + p_cdc->line_coding = ((cdc_line_coding_t) CFG_TUH_CDC_LINE_CODING_ON_ENUM_CH34X); + TU_ASSERT (ch34x_write_reg(p_cdc, TU_U16(CH341_REG_0x0F, CH341_REG_0x2C), 0x0007, ch34x_process_config, CONFIG_CH34X_FLOW_CONTROL),); + break; + + case CONFIG_CH34X_FLOW_CONTROL: + // no hardware flow control + TU_ASSERT (ch34x_write_reg(p_cdc, TU_U16(CH341_REG_0x27, CH341_REG_0x27), 0x0000, ch34x_process_config, CONFIG_CH34X_MODEM_CONTROL),); + break; + + case CONFIG_CH34X_MODEM_CONTROL: + // !always! set modem controls RTS/DTR (CH34x has no reset state after CH34X_REQ_SERIAL_INIT) + TU_ASSERT (ch34x_set_modem_ctrl(p_cdc, CFG_TUH_CDC_LINE_CONTROL_ON_ENUM, ch34x_process_config, CONFIG_CH34X_COMPLETE),); + break; + + case CONFIG_CH34X_COMPLETE: + set_config_complete(p_cdc, idx, itf_num); + break; + + default: + TU_ASSERT (false,); + break; + } +} + +//------------- CH34x helper -------------// + +// calculate divisor and prescaler for baudrate, return it as 16-bit combined value +static uint16_t ch34x_get_divisor_prescaler(uint32_t baval) { + uint8_t a; + uint8_t b; + uint32_t c; + + TU_VERIFY(baval != 0 && baval <= 2000000, 0); + switch (baval) { + case 921600: + a = 0xf3; + b = 7; + break; + + case 307200: + a = 0xd9; + b = 7; + break; + + default: + if (baval > 6000000 / 255) { + b = 3; + c = 6000000; + } else if (baval > 750000 / 255) { + b = 2; + c = 750000; + } else if (baval > 93750 / 255) { + b = 1; + c = 93750; + } else { + b = 0; + c = 11719; + } + a = (uint8_t) (c / baval); + if (a == 0 || a == 0xFF) { + return 0; + } + if ((c / a - baval) > (baval - c / (a + 1))) { + a++; + } + a = (uint8_t) (256 - a); + break; + } + + // reg divisor = a, reg prescaler = b + // According to linux code we need to set bit 7 of UCHCOM_REG_BPS_PRE, + // otherwise the chip will buffer data. + return (uint16_t) ((uint16_t)a << 8 | 0x80 | b); +} + +// calculate lcr value from data coding +static uint8_t ch34x_get_lcr(uint8_t stop_bits, uint8_t parity, uint8_t data_bits) { + uint8_t lcr = CH34X_LCR_ENABLE_RX | CH34X_LCR_ENABLE_TX; + TU_VERIFY(data_bits >= 5 && data_bits <= 8, 0); + lcr |= (uint8_t) (data_bits - 5); + + switch(parity) { + case CDC_LINE_CODING_PARITY_NONE: + break; + + case CDC_LINE_CODING_PARITY_ODD: + lcr |= CH34X_LCR_ENABLE_PAR; + break; + + case CDC_LINE_CODING_PARITY_EVEN: + lcr |= CH34X_LCR_ENABLE_PAR | CH34X_LCR_PAR_EVEN; + break; + + case CDC_LINE_CODING_PARITY_MARK: + lcr |= CH34X_LCR_ENABLE_PAR | CH34X_LCR_MARK_SPACE; + break; + + case CDC_LINE_CODING_PARITY_SPACE: + lcr |= CH34X_LCR_ENABLE_PAR | CH34X_LCR_MARK_SPACE | CH34X_LCR_PAR_EVEN; + break; + + default: break; + } + + // 1.5 stop bits not supported + TU_VERIFY(stop_bits != CDC_LINE_CODING_STOP_BITS_1_5, 0); + if (stop_bits == CDC_LINE_CODING_STOP_BITS_2) { + lcr |= CH34X_LCR_STOP_BITS_2; + } + + return lcr; +} + + +#endif // CFG_TUH_CDC_CH34X + #endif diff --git a/src/class/cdc/cdc_host.h b/src/class/cdc/cdc_host.h index 9e5edd94e..d512a23a5 100644 --- a/src/class/cdc/cdc_host.h +++ b/src/class/cdc/cdc_host.h @@ -148,8 +148,11 @@ bool tuh_cdc_set_control_line_state(uint8_t idx, uint16_t line_state, tuh_xfer_c // Request to set baudrate bool tuh_cdc_set_baudrate(uint8_t idx, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data); -// Request to Set Line Coding (ACM only) -// Should only use if you don't work with serial devices such as FTDI/CP210x +// Request to set data format +bool tuh_cdc_set_data_format(uint8_t idx, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, tuh_xfer_cb_t complete_cb, uintptr_t user_data); + +// Request to Set Line Coding = baudrate + data format +// Note: only implemented by ACM and CH34x, not supported by FTDI and CP210x yet bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data); // Request to Get Line Coding (ACM only) @@ -159,15 +162,13 @@ bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding, // Connect by set both DTR, RTS TU_ATTR_ALWAYS_INLINE static inline -bool tuh_cdc_connect(uint8_t idx, tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ +bool tuh_cdc_connect(uint8_t idx, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return tuh_cdc_set_control_line_state(idx, CDC_CONTROL_LINE_STATE_DTR | CDC_CONTROL_LINE_STATE_RTS, complete_cb, user_data); } // Disconnect by clear both DTR, RTS TU_ATTR_ALWAYS_INLINE static inline -bool tuh_cdc_disconnect(uint8_t idx, tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ +bool tuh_cdc_disconnect(uint8_t idx, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return tuh_cdc_set_control_line_state(idx, 0x00, complete_cb, user_data); } diff --git a/src/class/cdc/serial/ch34x.h b/src/class/cdc/serial/ch34x.h new file mode 100644 index 000000000..c18066f57 --- /dev/null +++ b/src/class/cdc/serial/ch34x.h @@ -0,0 +1,84 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2023 Heiko Kuester + * + * 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 _CH34X_H_ +#define _CH34X_H_ + +// There is no official documentation for the CH34x (CH340, CH341) chips. Reference can be found +// - https://github.com/WCHSoftGroup/ch341ser_linux +// - https://github.com/torvalds/linux/blob/master/drivers/usb/serial/ch341.c +// - https://github.com/freebsd/freebsd-src/blob/main/sys/dev/usb/serial/uchcom.c + +// set line_coding @ enumeration +#ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM +#define CFG_TUH_CDC_LINE_CODING_ON_ENUM_CH34X CFG_TUH_CDC_LINE_CODING_ON_ENUM +#else // this default is necessary to work properly +#define CFG_TUH_CDC_LINE_CODING_ON_ENUM_CH34X { 9600, CDC_LINE_CONDING_STOP_BITS_1, CDC_LINE_CODING_PARITY_NONE, 8 } +#endif + +// USB requests +#define CH34X_REQ_READ_VERSION 0x5F // dec 95 +#define CH34X_REQ_WRITE_REG 0x9A // dec 154 +#define CH34X_REQ_READ_REG 0x95 // dec 149 +#define CH34X_REQ_SERIAL_INIT 0xA1 // dec 161 +#define CH34X_REQ_MODEM_CTRL 0xA4 // dev 164 + +// registers +#define CH34X_REG_BREAK 0x05 +#define CH34X_REG_PRESCALER 0x12 +#define CH34X_REG_DIVISOR 0x13 +#define CH34X_REG_LCR 0x18 +#define CH34X_REG_LCR2 0x25 +#define CH34X_REG_MCR_MSR 0x06 +#define CH34X_REG_MCR_MSR2 0x07 +#define CH34X_NBREAK_BITS 0x01 + +#define CH341_REG_0x0F 0x0F // undocumented register +#define CH341_REG_0x2C 0x2C // undocumented register +#define CH341_REG_0x27 0x27 // hardware flow control (cts/rts) + +#define CH34X_REG16_DIVISOR_PRESCALER TU_U16(CH34X_REG_DIVISOR, CH34X_REG_PRESCALER) +#define CH32X_REG16_LCR2_LCR TU_U16(CH34X_REG_LCR2, CH34X_REG_LCR) + +// modem control bits +#define CH34X_BIT_RTS ( 1 << 6 ) +#define CH34X_BIT_DTR ( 1 << 5 ) + +// line control bits +#define CH34X_LCR_ENABLE_RX 0x80 +#define CH34X_LCR_ENABLE_TX 0x40 +#define CH34X_LCR_MARK_SPACE 0x20 +#define CH34X_LCR_PAR_EVEN 0x10 +#define CH34X_LCR_ENABLE_PAR 0x08 +#define CH34X_LCR_PAR_MASK 0x38 // all parity bits +#define CH34X_LCR_STOP_BITS_2 0x04 +#define CH34X_LCR_CS8 0x03 +#define CH34X_LCR_CS7 0x02 +#define CH34X_LCR_CS6 0x01 +#define CH34X_LCR_CS5 0x00 +#define CH34X_LCR_CS_MASK 0x03 // all CSx bits + +#endif /* _CH34X_H_ */ diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index db52b503f..709fa3dd8 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -50,6 +50,7 @@ typedef struct uint8_t itf_num; uint8_t ep_in; uint8_t ep_out; + bool mounted; // Enumeration is complete uint8_t itf_protocol; // None, Keyboard, Mouse uint8_t protocol_mode; // Boot (0) or Report protocol (1) @@ -139,7 +140,8 @@ uint8_t tuh_hid_itf_get_total_count(void) bool tuh_hid_mounted(uint8_t daddr, uint8_t idx) { hidh_interface_t* p_hid = get_hid_itf(daddr, idx); - return p_hid != NULL; + TU_VERIFY(p_hid); + return p_hid->mounted; } bool tuh_hid_itf_get_info(uint8_t daddr, uint8_t idx, tuh_itf_info_t* info) @@ -463,6 +465,7 @@ void hidh_close(uint8_t daddr) TU_LOG_DRV(" HIDh close addr = %u index = %u\r\n", daddr, i); if(tuh_hid_umount_cb) tuh_hid_umount_cb(daddr, i); p_hid->daddr = 0; + p_hid->mounted = false; } } } @@ -632,6 +635,7 @@ static void config_driver_mount_complete(uint8_t daddr, uint8_t idx, uint8_t con { hidh_interface_t* p_hid = get_hid_itf(daddr, idx); TU_VERIFY(p_hid, ); + p_hid->mounted = true; // enumeration is complete if (tuh_hid_mount_cb) tuh_hid_mount_cb(daddr, idx, desc_report, desc_len); diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index 389a29696..a68cb2156 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -49,10 +49,8 @@ typedef struct uint8_t rx_ff_buf[CFG_TUD_VENDOR_RX_BUFSIZE]; uint8_t tx_ff_buf[CFG_TUD_VENDOR_TX_BUFSIZE]; -#if CFG_FIFO_MUTEX - osal_mutex_def_t rx_ff_mutex; - osal_mutex_def_t tx_ff_mutex; -#endif + OSAL_MUTEX_DEF(rx_ff_mutex); + OSAL_MUTEX_DEF(tx_ff_mutex); // Endpoint Transfer buffer CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_VENDOR_EPSIZE]; @@ -183,10 +181,8 @@ void vendord_init(void) tu_fifo_config(&p_itf->rx_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); -#if CFG_FIFO_MUTEX tu_fifo_config_mutex(&p_itf->rx_ff, NULL, osal_mutex_create(&p_itf->rx_ff_mutex)); tu_fifo_config_mutex(&p_itf->tx_ff, osal_mutex_create(&p_itf->tx_ff_mutex), NULL); -#endif } } diff --git a/src/class/video/video.h b/src/class/video/video.h index d9880c291..6319c6536 100644 --- a/src/class/video/video.h +++ b/src/class/video/video.h @@ -29,6 +29,10 @@ #include "common/tusb_common.h" +enum { + VIDEO_BCD_1_50 = 0x0150, +}; + // Table 3-19 Color Matching Descriptor typedef enum { VIDEO_COLOR_PRIMARIES_UNDEFINED = 0x00, @@ -198,55 +202,98 @@ typedef enum { } video_terminal_type_t; //--------------------------------------------------------------------+ -// Descriptors +// Video Control (VC) Descriptors //--------------------------------------------------------------------+ /* 2.3.4.2 */ +#define tusb_desc_video_control_header_nitf_t(_nitf) \ + struct TU_ATTR_PACKED { \ + uint8_t bLength; \ + uint8_t bDescriptorType; \ + uint8_t bDescriptorSubType; \ + uint16_t bcdUVC; \ + uint16_t wTotalLength; \ + uint32_t dwClockFrequency; /* deprecated */ \ + uint8_t bInCollection; \ + uint8_t baInterfaceNr[_nitf]; \ + } + +typedef tusb_desc_video_control_header_nitf_t() tusb_desc_video_control_header_t; +typedef tusb_desc_video_control_header_nitf_t(1) tusb_desc_video_control_header_1itf_t; +typedef tusb_desc_video_control_header_nitf_t(2) tusb_desc_video_control_header_2itf_t; +typedef tusb_desc_video_control_header_nitf_t(3) tusb_desc_video_control_header_3itf_t; +typedef tusb_desc_video_control_header_nitf_t(4) tusb_desc_video_control_header_4itf_t; + typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; uint8_t bDescriptorSubType; - uint16_t bcdUVC; - uint16_t wTotalLength; - uint32_t dwClockFrequency; - uint8_t bInCollection; - uint8_t baInterfaceNr[]; -} tusb_desc_cs_video_ctl_itf_hdr_t; + uint8_t bTerminalID; + uint16_t wTerminalType; + uint8_t bAssocTerminal; + uint8_t iTerminal; +} tusb_desc_video_control_input_terminal_t; + +TU_VERIFY_STATIC(sizeof(tusb_desc_video_control_input_terminal_t) == 8, "size is not correct"); -/* 2.4.3.3 */ typedef struct TU_ATTR_PACKED { - uint8_t bHeaderLength; - union { - uint8_t bmHeaderInfo; - struct { - uint8_t FrameID: 1; - uint8_t EndOfFrame: 1; - uint8_t PresentationTime: 1; - uint8_t SourceClockReference: 1; - uint8_t PayloadSpecific: 1; - uint8_t StillImage: 1; - uint8_t Error: 1; - uint8_t EndOfHeader: 1; - }; - }; -} tusb_video_payload_header_t; + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bTerminalID; + uint16_t wTerminalType; + uint8_t bAssocTerminal; + uint8_t bSourceID; + uint8_t iTerminal; +} tusb_desc_video_control_output_terminal_t; + +TU_VERIFY_STATIC(sizeof(tusb_desc_video_control_output_terminal_t) == 9, "size is not correct"); + +typedef struct TU_ATTR_PACKED { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bTerminalID; + uint16_t wTerminalType; + uint8_t bAssocTerminal; + uint8_t iTerminal; + + uint16_t wObjectiveFocalLengthMin; + uint16_t wObjectiveFocalLengthMax; + uint16_t wOcularFocalLength; + uint8_t bControlSize; + uint8_t bmControls[3]; +} tusb_desc_video_control_camera_terminal_t; + +TU_VERIFY_STATIC(sizeof(tusb_desc_video_control_camera_terminal_t) == 18, "size is not correct"); + +//--------------------------------------------------------------------+ +// Video Streaming (VS) Descriptors +//--------------------------------------------------------------------+ /* 3.9.2.1 */ -typedef struct TU_ATTR_PACKED { - uint8_t bLength; - uint8_t bDescriptorType; - uint8_t bDescriptorSubType; - uint8_t bNumFormats; - uint16_t wTotalLength; - uint8_t bEndpointAddress; - uint8_t bmInfo; - uint8_t bTerminalLink; - uint8_t bStillCaptureMethod; - uint8_t bTriggerSupport; - uint8_t bTriggerUsage; - uint8_t bControlSize; - uint8_t bmaControls[]; -} tusb_desc_cs_video_stm_itf_in_hdr_t; +#define tusb_desc_video_streaming_input_header_nbyte_t(_nb) \ + struct TU_ATTR_PACKED { \ + uint8_t bLength; \ + uint8_t bDescriptorType; \ + uint8_t bDescriptorSubType; \ + uint8_t bNumFormats; /* Number of video payload Format descriptors for this interface */ \ + uint16_t wTotalLength; \ + uint8_t bEndpointAddress; \ + uint8_t bmInfo; /* Bit 0: dynamic format change supported */ \ + uint8_t bTerminalLink; \ + uint8_t bStillCaptureMethod; \ + uint8_t bTriggerSupport; /* Hardware trigger supported */ \ + uint8_t bTriggerUsage; \ + uint8_t bControlSize; /* sizeof of each control item */ \ + uint8_t bmaControls[_nb]; \ + } + +typedef tusb_desc_video_streaming_input_header_nbyte_t() tusb_desc_video_streaming_input_header_t; +typedef tusb_desc_video_streaming_input_header_nbyte_t(1) tusb_desc_video_streaming_input_header_1byte_t; +typedef tusb_desc_video_streaming_input_header_nbyte_t(2) tusb_desc_video_streaming_input_header_2byte_t; +typedef tusb_desc_video_streaming_input_header_nbyte_t(3) tusb_desc_video_streaming_input_header_3byte_t; +typedef tusb_desc_video_streaming_input_header_nbyte_t(4) tusb_desc_video_streaming_input_header_4byte_t; /* 3.9.2.2 */ typedef struct TU_ATTR_PACKED { @@ -259,7 +306,7 @@ typedef struct TU_ATTR_PACKED { uint8_t bTerminalLink; uint8_t bControlSize; uint8_t bmaControls[]; -} tusb_desc_cs_video_stm_itf_out_hdr_t; +} tusb_desc_video_streaming_output_header_t; typedef struct TU_ATTR_PACKED { uint8_t bLength; @@ -285,14 +332,33 @@ typedef struct TU_ATTR_PACKED { uint8_t bmaControls[]; } output; }; -} tusb_desc_cs_video_stm_itf_hdr_t; +} tusb_desc_video_streaming_inout_header_t; +// 3.9.2.6 Color Matching Descriptor +typedef struct TU_ATTR_PACKED { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bColorPrimaries; + uint8_t bTransferCharacteristics; + uint8_t bMatrixCoefficients; +} tusb_desc_video_streaming_color_matching_t; + +TU_VERIFY_STATIC(sizeof(tusb_desc_video_streaming_color_matching_t) == 6, "size is not correct"); + +//--------------------------------------------------------------------+ +// Format and Frame Descriptor +// Note: bFormatIndex & bFrameIndex are 1-based index +//--------------------------------------------------------------------+ + +//------------- Uncompressed -------------// +// Uncompressed payload specs: 3.1.1 format descriptor typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; uint8_t bDescriptorSubType; uint8_t bFormatIndex; - uint8_t bNumFrameDescriptors; + uint8_t bNumFrameDescriptors; // Number of frame descriptors for this format uint8_t guidFormat[16]; uint8_t bBitsPerPixel; uint8_t bDefaultFrameIndex; @@ -300,22 +366,65 @@ typedef struct TU_ATTR_PACKED { uint8_t bAspectRatioY; uint8_t bmInterlaceFlags; uint8_t bCopyProtect; -} tusb_desc_cs_video_fmt_uncompressed_t; +} tusb_desc_video_format_uncompressed_t; +// Uncompressed payload specs: 3.1.2 frame descriptor +#define tusb_desc_video_frame_uncompressed_nint_t(_nint) \ + struct TU_ATTR_PACKED { \ + uint8_t bLength; \ + uint8_t bDescriptorType; \ + uint8_t bDescriptorSubType; \ + uint8_t bFrameIndex; \ + uint8_t bmCapabilities; \ + uint16_t wWidth; \ + uint16_t wHeight; \ + uint32_t dwMinBitRate; \ + uint32_t dwMaxBitRate; \ + uint32_t dwMaxVideoFrameBufferSize; /* deprecated in 1.5 */ \ + uint32_t dwDefaultFrameInterval; \ + uint8_t bFrameIntervalType; \ + uint32_t dwFrameInterval[_nint]; \ + } + +typedef tusb_desc_video_frame_uncompressed_nint_t() tusb_desc_video_frame_uncompressed_t; +typedef tusb_desc_video_frame_uncompressed_nint_t(1) tusb_desc_video_frame_uncompressed_1int_t; +typedef tusb_desc_video_frame_uncompressed_nint_t(2) tusb_desc_video_frame_uncompressed_2int_t; +typedef tusb_desc_video_frame_uncompressed_nint_t(3) tusb_desc_video_frame_uncompressed_3int_t; +typedef tusb_desc_video_frame_uncompressed_nint_t(4) tusb_desc_video_frame_uncompressed_4int_t; + +// continuous = 3 intervals: min, max, step +typedef tusb_desc_video_frame_uncompressed_3int_t tusb_desc_video_frame_uncompressed_continuous_t; + +TU_VERIFY_STATIC(sizeof(tusb_desc_video_frame_uncompressed_continuous_t) == 38, "size is not correct"); + +//------------- MJPEG -------------// +// MJPEG payload specs: 3.1.1 format descriptor typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; uint8_t bDescriptorSubType; uint8_t bFormatIndex; uint8_t bNumFrameDescriptors; - uint8_t bmFlags; + uint8_t bmFlags; // Bit 0: fixed size samples (1 = yes) uint8_t bDefaultFrameIndex; uint8_t bAspectRatioX; uint8_t bAspectRatioY; uint8_t bmInterlaceFlags; uint8_t bCopyProtect; -} tusb_desc_cs_video_fmt_mjpeg_t; +} tusb_desc_video_format_mjpeg_t; +// MJPEG payload specs: 3.1.2 frame descriptor (same as uncompressed) +typedef tusb_desc_video_frame_uncompressed_t tusb_desc_video_frame_mjpeg_t; +typedef tusb_desc_video_frame_uncompressed_1int_t tusb_desc_video_frame_mjpeg_1int_t; +typedef tusb_desc_video_frame_uncompressed_2int_t tusb_desc_video_frame_mjpeg_2int_t; +typedef tusb_desc_video_frame_uncompressed_3int_t tusb_desc_video_frame_mjpeg_3int_t; +typedef tusb_desc_video_frame_uncompressed_4int_t tusb_desc_video_frame_mjpeg_4int_t; + +// continuous = 3 intervals: min, max, step +typedef tusb_desc_video_frame_mjpeg_3int_t tusb_desc_video_frame_mjpeg_continuous_t; + +//------------- DV -------------// +// DV payload specs: 3.1.1 typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; @@ -323,8 +432,9 @@ typedef struct TU_ATTR_PACKED { uint8_t bFormatIndex; uint32_t dwMaxVideoFrameBufferSize; /* deprecated */ uint8_t bFormatType; -} tusb_desc_cs_video_fmt_dv_t; +} tusb_desc_video_format_dv_t; +// Frame Based payload specs: 3.1.1 typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; @@ -339,25 +449,7 @@ typedef struct TU_ATTR_PACKED { uint8_t bmInterlaceFlags; uint8_t bCopyProtect; uint8_t bVaribaleSize; -} tusb_desc_cs_video_fmt_frame_based_t; - -typedef struct TU_ATTR_PACKED { - uint8_t bLength; - uint8_t bDescriptorType; - uint8_t bDescriptorSubType; - uint8_t bFrameIndex; - uint8_t bmCapabilities; - uint16_t wWidth; - uint16_t wHeight; - uint32_t dwMinBitRate; - uint32_t dwMaxBitRate; - uint32_t dwMaxVideoFrameBufferSize; /* deprecated */ - uint32_t dwDefaultFrameInterval; - uint8_t bFrameIntervalType; - uint32_t dwFrameInterval[]; -} tusb_desc_cs_video_frm_uncompressed_t; - -typedef tusb_desc_cs_video_frm_uncompressed_t tusb_desc_cs_video_frm_mjpeg_t; +} tusb_desc_video_format_framebased_t; typedef struct TU_ATTR_PACKED { uint8_t bLength; @@ -373,12 +465,30 @@ typedef struct TU_ATTR_PACKED { uint8_t bFrameIntervalType; uint32_t dwBytesPerLine; uint32_t dwFrameInterval[]; -} tusb_desc_cs_video_frm_frame_based_t; +} tusb_desc_video_frame_framebased_t; //--------------------------------------------------------------------+ // Requests //--------------------------------------------------------------------+ +/* 2.4.3.3 */ +typedef struct TU_ATTR_PACKED { + uint8_t bHeaderLength; + union { + uint8_t bmHeaderInfo; + struct { + uint8_t FrameID: 1; + uint8_t EndOfFrame: 1; + uint8_t PresentationTime: 1; + uint8_t SourceClockReference: 1; + uint8_t PayloadSpecific: 1; + uint8_t StillImage: 1; + uint8_t Error: 1; + uint8_t EndOfHeader: 1; + }; + }; +} tusb_video_payload_header_t; + /* 4.3.1.1 */ typedef struct TU_ATTR_PACKED { union { @@ -537,7 +647,7 @@ TU_VERIFY_STATIC( sizeof(video_probe_and_commit_control_t) == 48, "size is not c /* Motion-JPEG 3.1.1 Table 3-2 and 3-4 */ #define TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_DISC(_frmidx, _cap, _width, _height, _minbr, _maxbr, _maxfrmbufsz, _frminterval, ...) \ TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_DISC_LEN + (TU_ARGS_NUM(__VA_ARGS__)) * 4, \ - TUSB_DESC_CS_INTERFACE, VIDEO_CS_VS_INTERFACE_FRAME_MJPEG, \ + TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VS_FRAME_MJPEG, \ _frmidx, _cap, U16_TO_U8S_LE(_width), U16_TO_U8S_LE(_height), U32_TO_U8S_LE(_minbr), U32_TO_U8S_LE(_maxbr), \ U32_TO_U8S_LE(_maxfrmbufsz), U32_TO_U8S_LE(_frminterval), (TU_ARGS_NUM(__VA_ARGS__)), __VA_ARGS__ diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index 3b29454a3..1affd615e 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -50,17 +50,17 @@ typedef struct { tusb_desc_interface_t std; - tusb_desc_cs_video_ctl_itf_hdr_t ctl; + tusb_desc_video_control_header_t ctl; } tusb_desc_vc_itf_t; typedef struct { tusb_desc_interface_t std; - tusb_desc_cs_video_stm_itf_hdr_t stm; + tusb_desc_video_streaming_inout_header_t stm; } tusb_desc_vs_itf_t; typedef union { - tusb_desc_cs_video_ctl_itf_hdr_t ctl; - tusb_desc_cs_video_stm_itf_hdr_t stm; + tusb_desc_video_control_header_t ctl; + tusb_desc_video_streaming_inout_header_t stm; } tusb_desc_video_itf_hdr_t; typedef struct TU_ATTR_PACKED { @@ -78,9 +78,9 @@ typedef union { uint8_t bFormatIndex; uint8_t bNumFrameDescriptors; }; - tusb_desc_cs_video_fmt_uncompressed_t uncompressed; - tusb_desc_cs_video_fmt_mjpeg_t mjpeg; - tusb_desc_cs_video_fmt_frame_based_t frame_based; + tusb_desc_video_format_uncompressed_t uncompressed; + tusb_desc_video_format_mjpeg_t mjpeg; + tusb_desc_video_format_framebased_t frame_based; } tusb_desc_cs_video_fmt_t; typedef union { @@ -93,9 +93,9 @@ typedef union { uint16_t wWidth; uint16_t wHeight; }; - tusb_desc_cs_video_frm_uncompressed_t uncompressed; - tusb_desc_cs_video_frm_mjpeg_t mjpeg; - tusb_desc_cs_video_frm_frame_based_t frame_based; + tusb_desc_video_frame_uncompressed_t uncompressed; + tusb_desc_video_frame_mjpeg_t mjpeg; + tusb_desc_video_frame_framebased_t frame_based; } tusb_desc_cs_video_frm_t; /* video streaming interface */ @@ -434,8 +434,9 @@ static bool _update_streaming_parameters(videod_streaming_interface_t const *stm uint_fast32_t interval_ms = interval / 10000; TU_ASSERT(interval_ms); uint_fast32_t payload_size = (frame_size + interval_ms - 1) / interval_ms + 2; - if (CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE < payload_size) + if (CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE < payload_size) { payload_size = CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE; + } param->dwMaxPayloadTransferSize = payload_size; return true; } @@ -577,8 +578,9 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * } else { payload_size = (frame_size + interval_ms - 1) / interval_ms + 2; } - if (CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE < payload_size) + if (CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE < payload_size) { payload_size = CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE; + } param->dwMaxPayloadTransferSize = payload_size; } return true; diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index caeb5f2ef..1f08ce4ed 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -37,6 +37,7 @@ #define TU_ARRAY_SIZE(_arr) ( sizeof(_arr) / sizeof(_arr[0]) ) #define TU_MIN(_x, _y) ( ( (_x) < (_y) ) ? (_x) : (_y) ) #define TU_MAX(_x, _y) ( ( (_x) > (_y) ) ? (_x) : (_y) ) +#define TU_DIV_CEIL(n, d) (((n) + (d) - 1) / (d)) #define TU_U16(_high, _low) ((uint16_t) (((_high) << 8) | (_low))) #define TU_U16_HIGH(_u16) ((uint8_t) (((_u16) >> 8) & 0x00ff)) diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index fab680989..2c5dce723 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -44,43 +44,38 @@ *------------------------------------------------------------------*/ /// defined base on EHCI specs value for Endpoint Speed -typedef enum -{ +typedef enum { TUSB_SPEED_FULL = 0, TUSB_SPEED_LOW = 1, TUSB_SPEED_HIGH = 2, TUSB_SPEED_INVALID = 0xff, -}tusb_speed_t; +} tusb_speed_t; /// defined base on USB Specs Endpoint's bmAttributes -typedef enum -{ +typedef enum { TUSB_XFER_CONTROL = 0 , TUSB_XFER_ISOCHRONOUS , TUSB_XFER_BULK , TUSB_XFER_INTERRUPT -}tusb_xfer_type_t; +} tusb_xfer_type_t; -typedef enum -{ +typedef enum { TUSB_DIR_OUT = 0, TUSB_DIR_IN = 1, TUSB_DIR_IN_MASK = 0x80 -}tusb_dir_t; +} tusb_dir_t; -enum -{ +enum { TUSB_EPSIZE_BULK_FS = 64, - TUSB_EPSIZE_BULK_HS= 512, + TUSB_EPSIZE_BULK_HS = 512, TUSB_EPSIZE_ISO_FS_MAX = 1023, TUSB_EPSIZE_ISO_HS_MAX = 1024, }; -/// Isochronous End Point Attributes -typedef enum -{ +/// Isochronous Endpoint Attributes +typedef enum { TUSB_ISO_EP_ATT_NO_SYNC = 0x00, TUSB_ISO_EP_ATT_ASYNCHRONOUS = 0x04, TUSB_ISO_EP_ATT_ADAPTIVE = 0x08, @@ -88,11 +83,10 @@ typedef enum TUSB_ISO_EP_ATT_DATA = 0x00, ///< Data End Point TUSB_ISO_EP_ATT_EXPLICIT_FB = 0x10, ///< Feedback End Point TUSB_ISO_EP_ATT_IMPLICIT_FB = 0x20, ///< Data endpoint that also serves as an implicit feedback -}tusb_iso_ep_attribute_t; +} tusb_iso_ep_attribute_t; /// USB Descriptor Types -typedef enum -{ +typedef enum { TUSB_DESC_DEVICE = 0x01, TUSB_DESC_CONFIGURATION = 0x02, TUSB_DESC_STRING = 0x03, @@ -119,10 +113,9 @@ typedef enum TUSB_DESC_SUPERSPEED_ENDPOINT_COMPANION = 0x30, TUSB_DESC_SUPERSPEED_ISO_ENDPOINT_COMPANION = 0x31 -}tusb_desc_type_t; +} tusb_desc_type_t; -typedef enum -{ +typedef enum { TUSB_REQ_GET_STATUS = 0 , TUSB_REQ_CLEAR_FEATURE = 1 , TUSB_REQ_RESERVED = 2 , @@ -136,25 +129,22 @@ typedef enum TUSB_REQ_GET_INTERFACE = 10 , TUSB_REQ_SET_INTERFACE = 11 , TUSB_REQ_SYNCH_FRAME = 12 -}tusb_request_code_t; +} tusb_request_code_t; -typedef enum -{ +typedef enum { TUSB_REQ_FEATURE_EDPT_HALT = 0, TUSB_REQ_FEATURE_REMOTE_WAKEUP = 1, TUSB_REQ_FEATURE_TEST_MODE = 2 -}tusb_request_feature_selector_t; +} tusb_request_feature_selector_t; -typedef enum -{ +typedef enum { TUSB_REQ_TYPE_STANDARD = 0, TUSB_REQ_TYPE_CLASS, TUSB_REQ_TYPE_VENDOR, TUSB_REQ_TYPE_INVALID } tusb_request_type_t; -typedef enum -{ +typedef enum { TUSB_REQ_RCPT_DEVICE =0, TUSB_REQ_RCPT_INTERFACE, TUSB_REQ_RCPT_ENDPOINT, @@ -162,8 +152,7 @@ typedef enum } tusb_request_recipient_t; // https://www.usb.org/defined-class-codes -typedef enum -{ +typedef enum { TUSB_CLASS_UNSPECIFIED = 0 , TUSB_CLASS_AUDIO = 1 , TUSB_CLASS_CDC = 2 , @@ -187,26 +176,23 @@ typedef enum TUSB_CLASS_MISC = 0xEF , TUSB_CLASS_APPLICATION_SPECIFIC = 0xFE , TUSB_CLASS_VENDOR_SPECIFIC = 0xFF -}tusb_class_code_t; +} tusb_class_code_t; typedef enum { MISC_SUBCLASS_COMMON = 2 }misc_subclass_type_t; -typedef enum -{ +typedef enum { MISC_PROTOCOL_IAD = 1 -}misc_protocol_type_t; +} misc_protocol_type_t; -typedef enum -{ +typedef enum { APP_SUBCLASS_USBTMC = 0x03, APP_SUBCLASS_DFU_RUNTIME = 0x01 } app_subclass_type_t; -typedef enum -{ +typedef enum { DEVICE_CAPABILITY_WIRELESS_USB = 0x01, DEVICE_CAPABILITY_USB20_EXTENSION = 0x02, DEVICE_CAPABILITY_SUPERSPEED_USB = 0x03, @@ -223,7 +209,7 @@ typedef enum DEVICE_CAPABILITY_AUTHENTICATION = 0x0E, DEVICE_CAPABILITY_BILLBOARD_EX = 0x0F, DEVICE_CAPABILITY_CONFIGURATION_SUMMARY = 0x10 -}device_capability_type_t; +} device_capability_type_t; enum { TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP = TU_BIT(5), @@ -235,28 +221,25 @@ enum { //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ -typedef enum -{ +typedef enum { XFER_RESULT_SUCCESS = 0, XFER_RESULT_FAILED, XFER_RESULT_STALLED, XFER_RESULT_TIMEOUT, XFER_RESULT_INVALID -}xfer_result_t; +} xfer_result_t; -enum // TODO remove -{ +// TODO remove +enum { DESC_OFFSET_LEN = 0, DESC_OFFSET_TYPE = 1 }; -enum -{ +enum { INTERFACE_INVALID_NUMBER = 0xff }; -typedef enum -{ +typedef enum { MS_OS_20_SET_HEADER_DESCRIPTOR = 0x00, MS_OS_20_SUBSET_HEADER_CONFIGURATION = 0x01, MS_OS_20_SUBSET_HEADER_FUNCTION = 0x02, @@ -268,16 +251,14 @@ typedef enum MS_OS_20_FEATURE_VENDOR_REVISION = 0x08 } microsoft_os_20_type_t; -enum -{ +enum { CONTROL_STAGE_IDLE, CONTROL_STAGE_SETUP, CONTROL_STAGE_DATA, CONTROL_STAGE_ACK }; -enum -{ +enum { TUSB_INDEX_INVALID_8 = 0xFFu }; @@ -290,8 +271,7 @@ TU_ATTR_PACKED_BEGIN TU_ATTR_BIT_FIELD_ORDER_BEGIN /// USB Device Descriptor -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. uint8_t bDescriptorType ; ///< DEVICE Descriptor Type. uint16_t bcdUSB ; ///< BUSB Specification Release Number in Binary-Coded Decimal (i.e., 2.10 is 210H). This field identifies the release of the USB Specification with which the device and its descriptors are compliant. @@ -314,8 +294,7 @@ typedef struct TU_ATTR_PACKED TU_VERIFY_STATIC( sizeof(tusb_desc_device_t) == 18, "size is not correct"); // USB Binary Device Object Store (BOS) Descriptor -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes uint8_t bDescriptorType ; ///< CONFIGURATION Descriptor Type uint16_t wTotalLength ; ///< Total length of data returned for this descriptor @@ -325,8 +304,7 @@ typedef struct TU_ATTR_PACKED TU_VERIFY_STATIC( sizeof(tusb_desc_bos_t) == 5, "size is not correct"); /// USB Configuration Descriptor -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes uint8_t bDescriptorType ; ///< CONFIGURATION Descriptor Type uint16_t wTotalLength ; ///< Total length of data returned for this configuration. Includes the combined length of all descriptors (configuration, interface, endpoint, and class- or vendor-specific) returned for this configuration. @@ -341,8 +319,7 @@ typedef struct TU_ATTR_PACKED TU_VERIFY_STATIC( sizeof(tusb_desc_configuration_t) == 9, "size is not correct"); /// USB Interface Descriptor -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes uint8_t bDescriptorType ; ///< INTERFACE Descriptor Type @@ -358,8 +335,7 @@ typedef struct TU_ATTR_PACKED TU_VERIFY_STATIC( sizeof(tusb_desc_interface_t) == 9, "size is not correct"); /// USB Endpoint Descriptor -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { uint8_t bLength ; // Size of this descriptor in bytes uint8_t bDescriptorType ; // ENDPOINT Descriptor Type @@ -379,8 +355,7 @@ typedef struct TU_ATTR_PACKED TU_VERIFY_STATIC( sizeof(tusb_desc_endpoint_t) == 7, "size is not correct"); /// USB Other Speed Configuration Descriptor -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of descriptor uint8_t bDescriptorType ; ///< Other_speed_Configuration Type uint16_t wTotalLength ; ///< Total length of data returned @@ -393,8 +368,7 @@ typedef struct TU_ATTR_PACKED } tusb_desc_other_speed_t; /// USB Device Qualifier Descriptor -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of descriptor uint8_t bDescriptorType ; ///< Device Qualifier Type uint16_t bcdUSB ; ///< USB specification version number (e.g., 0200H for V2.00) @@ -411,8 +385,7 @@ typedef struct TU_ATTR_PACKED TU_VERIFY_STATIC( sizeof(tusb_desc_device_qualifier_t) == 10, "size is not correct"); /// USB Interface Association Descriptor (IAD ECN) -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of descriptor uint8_t bDescriptorType ; ///< Other_speed_Configuration Type @@ -426,17 +399,17 @@ typedef struct TU_ATTR_PACKED uint8_t iFunction ; ///< Index of the string descriptor describing the interface association. } tusb_desc_interface_assoc_t; +TU_VERIFY_STATIC( sizeof(tusb_desc_interface_assoc_t) == 8, "size is not correct"); + // USB String Descriptor -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes uint8_t bDescriptorType ; ///< Descriptor Type uint16_t unicode_string[]; } tusb_desc_string_t; // USB Binary Device Object Store (BOS) -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType ; uint8_t bDevCapabilityType; @@ -445,9 +418,8 @@ typedef struct TU_ATTR_PACKED uint8_t CapabilityData[]; } tusb_desc_bos_platform_t; -// USB WebuSB URL Descriptor -typedef struct TU_ATTR_PACKED -{ +// USB WebUSB URL Descriptor +typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; uint8_t bScheme; @@ -455,8 +427,7 @@ typedef struct TU_ATTR_PACKED } tusb_desc_webusb_url_t; // DFU Functional Descriptor -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; @@ -481,7 +452,7 @@ typedef struct TU_ATTR_PACKED // //--------------------------------------------------------------------+ -typedef struct TU_ATTR_PACKED{ +typedef struct TU_ATTR_PACKED { union { struct TU_ATTR_PACKED { uint8_t recipient : 5; ///< Recipient type tusb_request_recipient_t. @@ -500,7 +471,6 @@ typedef struct TU_ATTR_PACKED{ TU_VERIFY_STATIC( sizeof(tusb_control_request_t) == 8, "size is not correct"); - TU_ATTR_PACKED_END // End of all packed definitions TU_ATTR_BIT_FIELD_ORDER_END @@ -509,36 +479,30 @@ TU_ATTR_BIT_FIELD_ORDER_END //--------------------------------------------------------------------+ // Get direction from Endpoint address -TU_ATTR_ALWAYS_INLINE static inline tusb_dir_t tu_edpt_dir(uint8_t addr) -{ +TU_ATTR_ALWAYS_INLINE static inline tusb_dir_t tu_edpt_dir(uint8_t addr) { return (addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT; } // Get Endpoint number from address -TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_edpt_number(uint8_t addr) -{ +TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_edpt_number(uint8_t addr) { return (uint8_t)(addr & (~TUSB_DIR_IN_MASK)); } -TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_edpt_addr(uint8_t num, uint8_t dir) -{ +TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_edpt_addr(uint8_t num, uint8_t dir) { return (uint8_t)(num | (dir ? TUSB_DIR_IN_MASK : 0)); } -TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_edpt_packet_size(tusb_desc_endpoint_t const* desc_ep) -{ +TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_edpt_packet_size(tusb_desc_endpoint_t const* desc_ep) { return tu_le16toh(desc_ep->wMaxPacketSize) & TU_GENMASK(10, 0); } #if CFG_TUSB_DEBUG -TU_ATTR_ALWAYS_INLINE static inline const char *tu_edpt_dir_str(tusb_dir_t dir) -{ +TU_ATTR_ALWAYS_INLINE static inline const char *tu_edpt_dir_str(tusb_dir_t dir) { tu_static const char *str[] = {"out", "in"}; return str[dir]; } -TU_ATTR_ALWAYS_INLINE static inline const char *tu_edpt_type_str(tusb_xfer_type_t t) -{ +TU_ATTR_ALWAYS_INLINE static inline const char *tu_edpt_type_str(tusb_xfer_type_t t) { tu_static const char *str[] = {"control", "isochronous", "bulk", "interrupt"}; return str[t]; } @@ -549,21 +513,18 @@ TU_ATTR_ALWAYS_INLINE static inline const char *tu_edpt_type_str(tusb_xfer_type_ //--------------------------------------------------------------------+ // return next descriptor -TU_ATTR_ALWAYS_INLINE static inline uint8_t const * tu_desc_next(void const* desc) -{ +TU_ATTR_ALWAYS_INLINE static inline uint8_t const * tu_desc_next(void const* desc) { uint8_t const* desc8 = (uint8_t const*) desc; return desc8 + desc8[DESC_OFFSET_LEN]; } // get descriptor type -TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_type(void const* desc) -{ +TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_type(void const* desc) { return ((uint8_t const*) desc)[DESC_OFFSET_TYPE]; } // get descriptor length -TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_len(void const* desc) -{ +TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_len(void const* desc) { return ((uint8_t const*) desc)[DESC_OFFSET_LEN]; } diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index ac93632be..3e15d51c6 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -1130,8 +1130,8 @@ void dcd_int_handler(uint8_t rhport) { dwc2->gotgint = otg_int; } - if (int_status & GINTSTS_SOF) { - dwc2->gotgint = GINTSTS_SOF; + if(int_status & GINTSTS_SOF) { + dwc2->gintsts = GINTSTS_SOF; if (_sof_en) { uint32_t frame = (dwc2->dsts & (DSTS_FNSOF)) >> 8; diff --git a/src/tusb_option.h b/src/tusb_option.h index 57f026312..767323bdd 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -472,6 +472,23 @@ {0x10C4, 0xEA60}, {0x10C4, 0xEA70} #endif +#ifndef CFG_TUH_CDC_CH34X + // CH34X is not part of CDC class, only to re-use CDC driver API + #define CFG_TUH_CDC_CH34X 0 +#endif + +#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 */ \ + { 0x1a86, 0x7523 }, /* ch340 chip */ \ + { 0x1a86, 0xe523 }, /* ch330 chip */ \ + { 0x4348, 0x5523 }, /* ch340 custom chip */ \ + { 0x2184, 0x0057 }, /* overtaken from Linux Kernel driver /drivers/usb/serial/ch341.c */ \ + { 0x9986, 0x7523 } /* overtaken from Linux Kernel driver /drivers/usb/serial/ch341.c */ +#endif + #ifndef CFG_TUH_HID #define CFG_TUH_HID 0 #endif diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index 7c662aeea..7f03ce43f 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -364,8 +364,15 @@ def main(config_file, board): print(f' {test} ...', end='') - # flash firmware - ret = globals()[f'flash_{flasher}'](item, fw) + # flash firmware. It may fail randomly, retry a few times + for i in range(3): + ret = globals()[f'flash_{flasher}'](item, fw) + 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 From 31c9176b2b7405ec1937ab2114983804b7455451 Mon Sep 17 00:00:00 2001 From: Jerry Palacios Date: Wed, 7 Feb 2024 17:10:47 -0600 Subject: [PATCH 097/454] frdmmcxn947 board added --- hw/bsp/mcx/boards/frdmmcxn947/board.cmake | 21 ++ hw/bsp/mcx/boards/frdmmcxn947/board.h | 66 ++++ hw/bsp/mcx/boards/frdmmcxn947/board.mk | 11 + hw/bsp/mcx/boards/frdmmcxn947/clock_config.c | 338 +++++++++++++++++++ hw/bsp/mcx/boards/frdmmcxn947/clock_config.h | 177 ++++++++++ hw/bsp/mcx/boards/frdmmcxn947/pin_mux.c | 143 ++++++++ hw/bsp/mcx/boards/frdmmcxn947/pin_mux.h | 51 +++ 7 files changed, 807 insertions(+) create mode 100644 hw/bsp/mcx/boards/frdmmcxn947/board.cmake create mode 100644 hw/bsp/mcx/boards/frdmmcxn947/board.h create mode 100644 hw/bsp/mcx/boards/frdmmcxn947/board.mk create mode 100644 hw/bsp/mcx/boards/frdmmcxn947/clock_config.c create mode 100644 hw/bsp/mcx/boards/frdmmcxn947/clock_config.h create mode 100644 hw/bsp/mcx/boards/frdmmcxn947/pin_mux.c create mode 100644 hw/bsp/mcx/boards/frdmmcxn947/pin_mux.h diff --git a/hw/bsp/mcx/boards/frdmmcxn947/board.cmake b/hw/bsp/mcx/boards/frdmmcxn947/board.cmake new file mode 100644 index 000000000..8c3280743 --- /dev/null +++ b/hw/bsp/mcx/boards/frdmmcxn947/board.cmake @@ -0,0 +1,21 @@ +set(MCU_VARIANT MCXN947) +set(MCU_CORE MCXN947_cm33_core0) + +set(JLINK_DEVICE MCXN947_M33_0) +set(PYOCD_TARGET MCXN947) +set(NXPLINK_DEVICE MCXN947:MCXN947) + +set(PORT 1) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + CPU_MCXN947VDF_cm33_core0 + BOARD_TUD_RHPORT=${PORT} + # port 0 is fullspeed, port 1 is highspeed + BOARD_TUD_MAX_SPEED=$ + ) + target_sources(${TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/clock_config.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/pin_mux.c + ) +endfunction() diff --git a/hw/bsp/mcx/boards/frdmmcxn947/board.h b/hw/bsp/mcx/boards/frdmmcxn947/board.h new file mode 100644 index 000000000..acb73363f --- /dev/null +++ b/hw/bsp/mcx/boards/frdmmcxn947/board.h @@ -0,0 +1,66 @@ +/* + * 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 + +// LED +#define LED_GPIO GPIO0 +#define LED_CLK kCLOCK_Gpio0 +#define LED_PIN 10 // red +#define LED_STATE_ON 0 + +// WAKE button (Dummy, use unused pin +#define BUTTON_GPIO GPIO0 +#define BUTTON_CLK kCLOCK_Gpio0 +#define BUTTON_PIN 23 +#define BUTTON_STATE_ACTIVE 0 + +// UART +#define UART_DEV LPUART4 + +static inline void board_uart_init_clock(void) { + /* attach FRO 12M to FLEXCOMM4 */ + CLOCK_SetClkDiv(kCLOCK_DivFlexcom4Clk, 1u); + CLOCK_AttachClk(kFRO12M_to_FLEXCOMM4); + RESET_ClearPeripheralReset(kFC4_RST_SHIFT_RSTn); +} + +//#define UART_RX_PINMUX 0, 24, IOCON_PIO_DIG_FUNC1_EN +//#define UART_TX_PINMUX 0, 25, IOCON_PIO_DIG_FUNC1_EN + +// XTAL +#define XTAL0_CLK_HZ (24 * 1000 * 1000U) + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/hw/bsp/mcx/boards/frdmmcxn947/board.mk b/hw/bsp/mcx/boards/frdmmcxn947/board.mk new file mode 100644 index 000000000..aaad5e73e --- /dev/null +++ b/hw/bsp/mcx/boards/frdmmcxn947/board.mk @@ -0,0 +1,11 @@ +MCU_VARIANT = MCXN947 +MCU_CORE = MCXN947_cm33_core0 +PORT ?= 1 + +CFLAGS += -DCPU_MCXN947VDF_cm33_core0 + +JLINK_DEVICE = MCXN947_M33_0 +PYOCD_TARGET = MCXN947 + +# flash using pyocd +flash: flash-jlink diff --git a/hw/bsp/mcx/boards/frdmmcxn947/clock_config.c b/hw/bsp/mcx/boards/frdmmcxn947/clock_config.c new file mode 100644 index 000000000..37d2b4dfc --- /dev/null +++ b/hw/bsp/mcx/boards/frdmmcxn947/clock_config.c @@ -0,0 +1,338 @@ +/* + * Copyright 2022 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ +/* + * How to setup clock using clock driver functions: + * + * 1. Setup clock sources. + * + * 2. Set up wait states of the flash. + * + * 3. Set up all dividers. + * + * 4. Set up all selectors to provide selected clocks. + * + */ + +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Clocks v10.0 +processor: MCXN947 +package_id: MCXN947VDF +mcu_data: ksdk2_0 +processor_version: 0.12.3 +board: MCX-N9XX-EVK + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +#include "clock_config.h" +#include "fsl_clock.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ +/* System clock frequency. */ +// extern uint32_t SystemCoreClock; + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ +void BOARD_InitBootClocks(void) +{ + BOARD_BootClockPLL150M(); +} + +/******************************************************************************* + ******************** Configuration BOARD_BootClockFRO12M ********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockFRO12M +outputs: +- {id: CLK_144M_clock.outFreq, value: 144 MHz} +- {id: CLK_48M_clock.outFreq, value: 48 MHz} +- {id: FRO_12M_clock.outFreq, value: 12 MHz} +- {id: MAIN_clock.outFreq, value: 12 MHz} +- {id: Slow_clock.outFreq, value: 3 MHz} +- {id: System_clock.outFreq, value: 12 MHz} +- {id: gdet_clock.outFreq, value: 48 MHz} +- {id: trng_clock.outFreq, value: 48 MHz} +settings: +- {id: SCGMode, value: SIRC} +- {id: SCG.SCSSEL.sel, value: SCG.SIRC} +- {id: SCG_FIRCCSR_FIRCEN_CFG, value: Disabled} +- {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} +- {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockFRO12M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockFRO12M configuration + ******************************************************************************/ +void BOARD_BootClockFRO12M(void) +{ + /*!< Enable SCG clock */ + CLOCK_EnableClock(kCLOCK_Scg); + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO12M */ + + /*!< Set up dividers */ + CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U); /*!< Set AHBCLKDIV divider to value 1 */ + + /* Set SystemCoreClock variable */ + SystemCoreClock = BOARD_BOOTCLOCKFRO12M_CORE_CLOCK; +} + +/******************************************************************************* + ******************* Configuration BOARD_BootClockFROHF48M ********************* + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockFROHF48M +outputs: +- {id: CLK_144M_clock.outFreq, value: 144 MHz} +- {id: CLK_48M_clock.outFreq, value: 48 MHz} +- {id: FRO_12M_clock.outFreq, value: 12 MHz} +- {id: FRO_HF_clock.outFreq, value: 48 MHz} +- {id: MAIN_clock.outFreq, value: 48 MHz} +- {id: Slow_clock.outFreq, value: 12 MHz} +- {id: System_clock.outFreq, value: 48 MHz} +- {id: gdet_clock.outFreq, value: 48 MHz} +- {id: trng_clock.outFreq, value: 48 MHz} +settings: +- {id: SYSCON.FLEXCAN0CLKSEL.sel, value: NO_CLOCK} +- {id: SYSCON.FLEXCAN1CLKSEL.sel, value: NO_CLOCK} +- {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} +- {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockFROHF48M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockFROHF48M configuration + ******************************************************************************/ +void BOARD_BootClockFROHF48M(void) +{ + /*!< Enable SCG clock */ + CLOCK_EnableClock(kCLOCK_Scg); + + CLOCK_SetupFROHFClocking(48000000U); /*!< Enable FRO HF(48MHz) output */ + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO_HF */ + + /*!< Set up dividers */ + CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U); /*!< Set AHBCLKDIV divider to value 1 */ + + /* Set SystemCoreClock variable */ + SystemCoreClock = BOARD_BOOTCLOCKFROHF48M_CORE_CLOCK; +} + +/******************************************************************************* + ******************* Configuration BOARD_BootClockFROHF144M ******************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockFROHF144M +outputs: +- {id: CLK_144M_clock.outFreq, value: 144 MHz} +- {id: CLK_48M_clock.outFreq, value: 48 MHz} +- {id: FRO_12M_clock.outFreq, value: 12 MHz} +- {id: FRO_HF_clock.outFreq, value: 144 MHz} +- {id: MAIN_clock.outFreq, value: 144 MHz} +- {id: Slow_clock.outFreq, value: 18 MHz} +- {id: System_clock.outFreq, value: 72 MHz} +- {id: gdet_clock.outFreq, value: 48 MHz} +- {id: trng_clock.outFreq, value: 48 MHz} +settings: +- {id: SYSCON.AHBCLKDIV.scale, value: '2', locked: true} +- {id: SYSCON.FLEXCAN0CLKSEL.sel, value: NO_CLOCK} +- {id: SYSCON.FLEXCAN1CLKSEL.sel, value: NO_CLOCK} +- {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} +- {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} +sources: +- {id: SCG.FIRC.outFreq, value: 144 MHz} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockFROHF144M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockFROHF144M configuration + ******************************************************************************/ +void BOARD_BootClockFROHF144M(void) +{ + /*!< Enable SCG clock */ + CLOCK_EnableClock(kCLOCK_Scg); + + CLOCK_SetupFROHFClocking(144000000U); /*!< Enable FRO HF(144MHz) output */ + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO_HF */ + + /*!< Set up dividers */ + CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 2U); /*!< Set AHBCLKDIV divider to value 2 */ + + /* Set SystemCoreClock variable */ + SystemCoreClock = BOARD_BOOTCLOCKFROHF144M_CORE_CLOCK; +} + +/******************************************************************************* + ******************** Configuration BOARD_BootClockPLL150M ********************* + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockPLL150M +called_from_default_init: true +outputs: +- {id: CLK_144M_clock.outFreq, value: 144 MHz} +- {id: CLK_48M_clock.outFreq, value: 48 MHz} +- {id: FRO_12M_clock.outFreq, value: 12 MHz} +- {id: FRO_HF_clock.outFreq, value: 48 MHz} +- {id: MAIN_clock.outFreq, value: 150 MHz} +- {id: PLL0_CLK_clock.outFreq, value: 150 MHz} +- {id: Slow_clock.outFreq, value: 37.5 MHz} +- {id: System_clock.outFreq, value: 150 MHz} +- {id: gdet_clock.outFreq, value: 48 MHz} +- {id: trng_clock.outFreq, value: 48 MHz} +settings: +- {id: PLL0_Mode, value: Normal} +- {id: RunPowerMode, value: OD} +- {id: SCGMode, value: PLL0} +- {id: SCG.PLL0M_MULT.scale, value: '50', locked: true} +- {id: SCG.PLL0SRCSEL.sel, value: SCG.FIRC_48M} +- {id: SCG.PLL0_NDIV.scale, value: '8', locked: true} +- {id: SCG.SCSSEL.sel, value: SCG.PLL0_CLK} +- {id: SYSCON.FLEXCAN0CLKSEL.sel, value: NO_CLOCK} +- {id: SYSCON.FLEXCAN1CLKSEL.sel, value: NO_CLOCK} +- {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} +- {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockPLL150M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockPLL150M configuration + ******************************************************************************/ +void BOARD_BootClockPLL150M(void) +{ + /*!< Enable SCG clock */ + CLOCK_EnableClock(kCLOCK_Scg); + + CLOCK_SetupFROHFClocking(48000000U); /*!< Enable FRO HF(48MHz) output */ + + /*!< Set up PLL0 */ + const pll_setup_t pll0Setup = { + .pllctrl = SCG_APLLCTRL_SOURCE(1U) | SCG_APLLCTRL_SELI(27U) | SCG_APLLCTRL_SELP(13U), + .pllndiv = SCG_APLLNDIV_NDIV(8U), + .pllpdiv = SCG_APLLPDIV_PDIV(1U), + .pllmdiv = SCG_APLLMDIV_MDIV(50U), + .pllRate = 150000000U + }; + CLOCK_SetPLL0Freq(&pll0Setup); /*!< Configure PLL0 to the desired values */ + CLOCK_SetPll0MonitorMode(kSCG_Pll0MonitorDisable); /* Pll0 Monitor is disabled */ + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + CLOCK_AttachClk(kPLL0_to_MAIN_CLK); /*!< Switch MAIN_CLK to PLL0 */ + + /*!< Set up dividers */ + CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U); /*!< Set AHBCLKDIV divider to value 1 */ + + /* Set SystemCoreClock variable */ + SystemCoreClock = BOARD_BOOTCLOCKPLL150M_CORE_CLOCK; +} + +/******************************************************************************* + ******************** Configuration BOARD_BootClockPLL100M ********************* + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockPLL100M +outputs: +- {id: CLK_144M_clock.outFreq, value: 144 MHz} +- {id: CLK_48M_clock.outFreq, value: 48 MHz} +- {id: CLK_IN_clock.outFreq, value: 24 MHz} +- {id: FRO_12M_clock.outFreq, value: 12 MHz} +- {id: MAIN_clock.outFreq, value: 100 MHz} +- {id: PLL1_CLK_clock.outFreq, value: 100 MHz} +- {id: Slow_clock.outFreq, value: 25 MHz} +- {id: System_clock.outFreq, value: 100 MHz} +- {id: gdet_clock.outFreq, value: 48 MHz} +- {id: trng_clock.outFreq, value: 48 MHz} +settings: +- {id: PLL1_Mode, value: Normal} +- {id: SCGMode, value: PLL1} +- {id: SCG.PLL1M_MULT.scale, value: '100', locked: true} +- {id: SCG.PLL1_NDIV.scale, value: '6', locked: true} +- {id: SCG.PLL1_PDIV.scale, value: '4', locked: true} +- {id: SCG.SCSSEL.sel, value: SCG.PLL1_CLK} +- {id: SCG_FIRCCSR_FIRCEN_CFG, value: Disabled} +- {id: SCG_SOSCCSR_SOSCEN_CFG, value: Enabled} +- {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} +- {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} +sources: +- {id: SCG.SOSC.outFreq, value: 24 MHz, enabled: true} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockPLL100M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockPLL100M configuration + ******************************************************************************/ +void BOARD_BootClockPLL100M(void) +{ + /*!< Enable SCG clock */ + CLOCK_EnableClock(kCLOCK_Scg); + + CLOCK_SetupExtClocking(24000000U); + CLOCK_SetSysOscMonitorMode(kSCG_SysOscMonitorDisable); /* System OSC Clock Monitor is disabled */ + + /*!< Set up PLL1 */ + const pll_setup_t pll1Setup = { + .pllctrl = SCG_SPLLCTRL_SOURCE(0U) | SCG_SPLLCTRL_SELI(53U) | SCG_SPLLCTRL_SELP(26U), + .pllndiv = SCG_SPLLNDIV_NDIV(6U), + .pllpdiv = SCG_SPLLPDIV_PDIV(2U), + .pllmdiv = SCG_SPLLMDIV_MDIV(100U), + .pllRate = 100000000U + }; + CLOCK_SetPLL1Freq(&pll1Setup); /*!< Configure PLL1 to the desired values */ + CLOCK_SetPll1MonitorMode(kSCG_Pll1MonitorDisable); /* Pll1 Monitor is disabled */ + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + CLOCK_AttachClk(kPLL1_to_MAIN_CLK); /*!< Switch MAIN_CLK to PLL1 */ + + /*!< Set up dividers */ + CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U); /*!< Set AHBCLKDIV divider to value 1 */ + + /* Set SystemCoreClock variable */ + SystemCoreClock = BOARD_BOOTCLOCKPLL100M_CORE_CLOCK; +} diff --git a/hw/bsp/mcx/boards/frdmmcxn947/clock_config.h b/hw/bsp/mcx/boards/frdmmcxn947/clock_config.h new file mode 100644 index 000000000..c238a0423 --- /dev/null +++ b/hw/bsp/mcx/boards/frdmmcxn947/clock_config.h @@ -0,0 +1,177 @@ +/* + * Copyright 2022 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _CLOCK_CONFIG_H_ +#define _CLOCK_CONFIG_H_ + +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define BOARD_XTAL0_CLK_HZ 24000000U /*!< Board xtal frequency in Hz */ +#define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32K frequency in Hz */ + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes default configuration of clocks. + * + */ +void BOARD_InitBootClocks(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************** Configuration BOARD_BootClockFRO12M ********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockFRO12M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKFRO12M_CORE_CLOCK 12000000U /*!< Core clock frequency: 12000000Hz */ +#define BOARD_BOOTCLOCKFRO12M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ + + +/******************************************************************************* + * API for BOARD_BootClockFRO12M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockFRO12M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************* Configuration BOARD_BootClockFROHF48M ********************* + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockFROHF48M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKFROHF48M_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */ +#define BOARD_BOOTCLOCKFROHF48M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ + + +/******************************************************************************* + * API for BOARD_BootClockFROHF48M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockFROHF48M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************* Configuration BOARD_BootClockFROHF144M ******************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockFROHF144M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKFROHF144M_CORE_CLOCK 144000000U /*!< Core clock frequency: 144000000Hz */ +#define BOARD_BOOTCLOCKFROHF144M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ + + +/******************************************************************************* + * API for BOARD_BootClockFROHF144M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockFROHF144M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************** Configuration BOARD_BootClockPLL150M ********************* + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockPLL150M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKPLL150M_CORE_CLOCK 150000000U /*!< Core clock frequency: 150000000Hz */ +#define BOARD_BOOTCLOCKPLL150M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ + + +/******************************************************************************* + * API for BOARD_BootClockPLL150M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockPLL150M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************** Configuration BOARD_BootClockPLL100M ********************* + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockPLL100M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKPLL100M_CORE_CLOCK 100000000U /*!< Core clock frequency: 100000000Hz */ +#define BOARD_BOOTCLOCKPLL100M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ + + +/******************************************************************************* + * API for BOARD_BootClockPLL100M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockPLL100M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +#endif /* _CLOCK_CONFIG_H_ */ diff --git a/hw/bsp/mcx/boards/frdmmcxn947/pin_mux.c b/hw/bsp/mcx/boards/frdmmcxn947/pin_mux.c new file mode 100644 index 000000000..c33790ac5 --- /dev/null +++ b/hw/bsp/mcx/boards/frdmmcxn947/pin_mux.c @@ -0,0 +1,143 @@ +/* + * Copyright 2022 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Pins v12.0 +processor: MCXN947 +package_id: MCXN947VDF +mcu_data: ksdk2_0 +processor_version: 0.12.3 + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +#include "fsl_common.h" +#include "fsl_port.h" +#include "pin_mux.h" + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitBootPins + * Description : Calls initialization functions. + * + * END ****************************************************************************************************************/ +void BOARD_InitBootPins(void) +{ + BOARD_InitPins(); +} + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitPins: +- options: {callFromInitBoot: 'true', coreID: cm33_core0, enableClock: 'true'} +- pin_list: + - {pin_num: A1, peripheral: LPFlexcomm4, signal: LPFLEXCOMM_P0, pin_signal: PIO1_8/WUU0_IN10/LPTMR1_ALT3/TRACE_DATA0/FC4_P0/FC5_P4/CT_INP8/SCT0_OUT2/FLEXIO0_D16/PLU_OUT0/ENET0_TXD2/I3C1_SDA/TSI0_CH17/ADC1_A8, + slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable, pull_value: low, input_buffer: enable, + invert_input: normal} + - {pin_num: B1, peripheral: LPFlexcomm4, signal: LPFLEXCOMM_P1, pin_signal: PIO1_9/TRACE_DATA1/FC4_P1/FC5_P5/CT_INP9/SCT0_OUT3/FLEXIO0_D17/PLU_OUT1/ENET0_TXD3/I3C1_SCL/TSI0_CH18/ADC1_A9, + slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable, input_buffer: enable, invert_input: normal} + - {pin_num: B7, peripheral: GPIO0, signal: 'GPIO, 23', pin_signal: PIO0_23/WUU0_IN5/EWM0_OUT_b/FC1_P3/CT_INP3/FLEXIO0_D7/ADC0_A15/CMP2_IN2, direction: INPUT, slew_rate: fast, + open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, input_buffer: enable, invert_input: normal} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitPins(void) +{ + /* Enables the clock for PORT0: Enables clock */ + CLOCK_EnableClock(kCLOCK_Port0); + + /* Enables the clock for PORT1: Enables clock */ + CLOCK_EnableClock(kCLOCK_Port1); + + + const port_pin_config_t port1_8_pinA1_config = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Low internal pull resistor value is selected. */ + kPORT_LowPullResistor, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive input filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain output is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as FC4_P0 */ + kPORT_MuxAlt2, + /* Digital input enabled */ + kPORT_InputBufferEnable, + /* Digital input is not inverted */ + kPORT_InputNormal, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORT1_8 (pin A1) is configured as FC4_P0 */ + PORT_SetPinConfig(PORT1, 8U, &port1_8_pinA1_config); + + const port_pin_config_t port1_9_pinB1_config = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Low internal pull resistor value is selected. */ + kPORT_LowPullResistor, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive input filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain output is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as FC4_P1 */ + kPORT_MuxAlt2, + /* Digital input enabled */ + kPORT_InputBufferEnable, + /* Digital input is not inverted */ + kPORT_InputNormal, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORT1_9 (pin B1) is configured as FC4_P1 */ + PORT_SetPinConfig(PORT1, 9U, &port1_9_pinB1_config); + + const port_pin_config_t SW2 = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Low internal pull resistor value is selected. */ + kPORT_LowPullResistor, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive input filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain output is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as PIO0_23 */ + kPORT_MuxAlt0, + /* Digital input enabled */ + kPORT_InputBufferEnable, + /* Digital input is not inverted */ + kPORT_InputNormal, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORT0_23 (pin B7) is configured as PIO0_23 */ + PORT_SetPinConfig(PORT0, 23U, &SW2); +} +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/mcx/boards/frdmmcxn947/pin_mux.h b/hw/bsp/mcx/boards/frdmmcxn947/pin_mux.h new file mode 100644 index 000000000..40968c275 --- /dev/null +++ b/hw/bsp/mcx/boards/frdmmcxn947/pin_mux.h @@ -0,0 +1,51 @@ +/* + * Copyright 2022 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _PIN_MUX_H_ +#define _PIN_MUX_H_ + +/*! + * @addtogroup pin_mux + * @{ + */ + +/*********************************************************************************************************************** + * API + **********************************************************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Calls initialization functions. + * + */ +void BOARD_InitBootPins(void); + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitPins(void); + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ +#endif /* _PIN_MUX_H_ */ + +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ From bab25c2d568dc5a47a03421a1dd4a338040a7f40 Mon Sep 17 00:00:00 2001 From: Jerry Palacios Date: Wed, 7 Feb 2024 17:26:43 -0600 Subject: [PATCH 098/454] nxp-sdk pointing to Wavenumber repo --- tools/get_deps.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/get_deps.py b/tools/get_deps.py index d561a1b36..ef83beea9 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -50,9 +50,9 @@ deps_optional = { '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/nxp/mcux-sdk': ['https://github.com/wavenumber-eng/mcux-sdk.git', + 'main', + 'kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx mcxa imxrt'], 'hw/mcu/raspberry_pi/Pico-PIO-USB': ['https://github.com/sekigon-gonnoc/Pico-PIO-USB.git', '0f747aaa0c16f750bdfa2ba37ec25d6c8e1bc117', 'rp2040'], From 45454c53f1d429a314115701ba2360591b811f50 Mon Sep 17 00:00:00 2001 From: Jerry Palacios Date: Wed, 7 Feb 2024 18:33:19 -0600 Subject: [PATCH 099/454] frdmmcxa153 files added --- hw/bsp/mcxa/FreeRTOSConfig/FreeRTOSConfig.h | 149 ++++++ hw/bsp/mcxa/boards/frdmmcxa153/board.cmake | 18 + hw/bsp/mcxa/boards/frdmmcxa153/board.h | 66 +++ hw/bsp/mcxa/boards/frdmmcxa153/board.mk | 26 + hw/bsp/mcxa/boards/frdmmcxa153/clock_config.c | 468 ++++++++++++++++++ hw/bsp/mcxa/boards/frdmmcxa153/clock_config.h | 170 +++++++ hw/bsp/mcxa/boards/frdmmcxa153/pin_mux.c | 159 ++++++ hw/bsp/mcxa/boards/frdmmcxa153/pin_mux.h | 47 ++ hw/bsp/mcxa/debug.jlinkscript | 5 + hw/bsp/mcxa/family.c | 163 ++++++ hw/bsp/mcxa/family.cmake | 110 ++++ hw/bsp/mcxa/family.mk | 42 ++ src/common/tusb_mcu.h | 7 + src/portable/chipidea/ci_fs/ci_fs_mcxa.h | 47 ++ src/portable/chipidea/ci_fs/dcd_ci_fs.c | 2 + src/tusb_option.h | 1 + 16 files changed, 1480 insertions(+) create mode 100644 hw/bsp/mcxa/FreeRTOSConfig/FreeRTOSConfig.h create mode 100644 hw/bsp/mcxa/boards/frdmmcxa153/board.cmake create mode 100644 hw/bsp/mcxa/boards/frdmmcxa153/board.h create mode 100644 hw/bsp/mcxa/boards/frdmmcxa153/board.mk create mode 100644 hw/bsp/mcxa/boards/frdmmcxa153/clock_config.c create mode 100644 hw/bsp/mcxa/boards/frdmmcxa153/clock_config.h create mode 100644 hw/bsp/mcxa/boards/frdmmcxa153/pin_mux.c create mode 100644 hw/bsp/mcxa/boards/frdmmcxa153/pin_mux.h create mode 100644 hw/bsp/mcxa/debug.jlinkscript create mode 100644 hw/bsp/mcxa/family.c create mode 100644 hw/bsp/mcxa/family.cmake create mode 100644 hw/bsp/mcxa/family.mk create mode 100644 src/portable/chipidea/ci_fs/ci_fs_mcxa.h diff --git a/hw/bsp/mcxa/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/mcxa/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..6f10a7ab0 --- /dev/null +++ b/hw/bsp/mcxa/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 "fsl_device_registers.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<FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x0U)); + /* Specifies the operating voltage for the SRAM's read/write timing margin */ + sramOption.operateVoltage = kSPC_sramOperateAt1P0V; + sramOption.requestVoltageUpdate = true; + (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); + } + + CLOCK_SetupFRO12MClocking(); /*!< Setup FRO12M clock */ + + CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /* !< Switch MAIN_CLK to FRO12M */ + + /* The flow of decreasing voltage and frequency */ + if (coreFreq > BOARD_BOOTCLOCKFRO12M_CORE_CLOCK) { + /* Configure Flash to support different voltage level and frequency */ + FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x0U)); + /* Specifies the operating voltage for the SRAM's read/write timing margin */ + sramOption.operateVoltage = kSPC_sramOperateAt1P0V; + sramOption.requestVoltageUpdate = true; + (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); + /* Set the LDO_CORE VDD regulator level */ + ldoOption.CoreLDOVoltage = kSPC_CoreLDO_MidDriveVoltage; + ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; + (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); + } + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + + /*!< Set up dividers */ + CLOCK_SetClockDiv(kCLOCK_DivAHBCLK, 1U); /* !< Set AHBCLKDIV divider to value 1 */ + + /* Set SystemCoreClock variable */ + SystemCoreClock = BOARD_BOOTCLOCKFRO12M_CORE_CLOCK; +} +/******************************************************************************* + ******************** Configuration BOARD_BootClockFRO24M ********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockFRO24M +outputs: +- {id: CLK_1M_clock.outFreq, value: 1 MHz} +- {id: CLK_48M_clock.outFreq, value: 48 MHz} +- {id: CPU_clock.outFreq, value: 24 MHz} +- {id: FRO_12M_clock.outFreq, value: 12 MHz} +- {id: FRO_HF_DIV_clock.outFreq, value: 48 MHz} +- {id: FRO_HF_clock.outFreq, value: 48 MHz} +- {id: MAIN_clock.outFreq, value: 48 MHz} +- {id: Slow_clock.outFreq, value: 6 MHz} +- {id: System_clock.outFreq, value: 24 MHz} +settings: +- {id: MRCC.OSTIMERCLKSEL.sel, value: VBAT.CLK16K_1} +- {id: SYSCON.AHBCLKDIV.scale, value: '2', locked: true} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockFRO24M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockFRO24M configuration + ******************************************************************************/ +void BOARD_BootClockFRO24M(void) +{ + uint32_t coreFreq; + spc_active_mode_core_ldo_option_t ldoOption; + spc_sram_voltage_config_t sramOption; + + /* Get the CPU Core frequency */ + coreFreq = CLOCK_GetCoreSysClkFreq(); + + /* The flow of increasing voltage and frequency */ + if (coreFreq <= BOARD_BOOTCLOCKFRO24M_CORE_CLOCK) { + /* Set the LDO_CORE VDD regulator level */ + ldoOption.CoreLDOVoltage = kSPC_CoreLDO_MidDriveVoltage; + ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; + (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); + /* Configure Flash to support different voltage level and frequency */ + FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x0U)); + /* Specifies the operating voltage for the SRAM's read/write timing margin */ + sramOption.operateVoltage = kSPC_sramOperateAt1P0V; + sramOption.requestVoltageUpdate = true; + (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); + } + + CLOCK_SetupFROHFClocking(48000000U); /*!< Enable FRO HF(48MHz) output */ + + CLOCK_SetupFRO12MClocking(); /*!< Setup FRO12M clock */ + + CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /* !< Switch MAIN_CLK to FRO_HF */ + + /* The flow of decreasing voltage and frequency */ + if (coreFreq > BOARD_BOOTCLOCKFRO24M_CORE_CLOCK) { + /* Configure Flash to support different voltage level and frequency */ + FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x0U)); + /* Specifies the operating voltage for the SRAM's read/write timing margin */ + sramOption.operateVoltage = kSPC_sramOperateAt1P0V; + sramOption.requestVoltageUpdate = true; + (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); + /* Set the LDO_CORE VDD regulator level */ + ldoOption.CoreLDOVoltage = kSPC_CoreLDO_MidDriveVoltage; + ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; + (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); + } + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + + /*!< Set up dividers */ + CLOCK_SetClockDiv(kCLOCK_DivAHBCLK, 2U); /* !< Set AHBCLKDIV divider to value 2 */ + CLOCK_SetClockDiv(kCLOCK_DivFRO_HF_DIV, 1U); /* !< Set FROHFDIV divider to value 1 */ + + /* Set SystemCoreClock variable */ + SystemCoreClock = BOARD_BOOTCLOCKFRO24M_CORE_CLOCK; +} +/******************************************************************************* + ******************** Configuration BOARD_BootClockFRO48M ********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockFRO48M +outputs: +- {id: CLK_1M_clock.outFreq, value: 1 MHz} +- {id: CLK_48M_clock.outFreq, value: 48 MHz} +- {id: CPU_clock.outFreq, value: 48 MHz} +- {id: FRO_12M_clock.outFreq, value: 12 MHz} +- {id: FRO_HF_DIV_clock.outFreq, value: 48 MHz} +- {id: FRO_HF_clock.outFreq, value: 48 MHz} +- {id: MAIN_clock.outFreq, value: 48 MHz} +- {id: Slow_clock.outFreq, value: 12 MHz} +- {id: System_clock.outFreq, value: 48 MHz} +settings: +- {id: MRCC.OSTIMERCLKSEL.sel, value: VBAT.CLK16K_1} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockFRO48M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockFRO48M configuration + ******************************************************************************/ +void BOARD_BootClockFRO48M(void) +{ + uint32_t coreFreq; + spc_active_mode_core_ldo_option_t ldoOption; + spc_sram_voltage_config_t sramOption; + + /* Get the CPU Core frequency */ + coreFreq = CLOCK_GetCoreSysClkFreq(); + + /* The flow of increasing voltage and frequency */ + if (coreFreq <= BOARD_BOOTCLOCKFRO48M_CORE_CLOCK) { + /* Set the LDO_CORE VDD regulator level */ + ldoOption.CoreLDOVoltage = kSPC_CoreLDO_MidDriveVoltage; + ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; + (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); + /* Configure Flash to support different voltage level and frequency */ + FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x1U)); + /* Specifies the operating voltage for the SRAM's read/write timing margin */ + sramOption.operateVoltage = kSPC_sramOperateAt1P0V; + sramOption.requestVoltageUpdate = true; + (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); + } + + CLOCK_SetupFROHFClocking(48000000U); /*!< Enable FRO HF(48MHz) output */ + + CLOCK_SetupFRO12MClocking(); /*!< Setup FRO12M clock */ + + CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /* !< Switch MAIN_CLK to FRO_HF */ + + /* The flow of decreasing voltage and frequency */ + if (coreFreq > BOARD_BOOTCLOCKFRO48M_CORE_CLOCK) { + /* Configure Flash to support different voltage level and frequency */ + FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x1U)); + /* Specifies the operating voltage for the SRAM's read/write timing margin */ + sramOption.operateVoltage = kSPC_sramOperateAt1P0V; + sramOption.requestVoltageUpdate = true; + (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); + /* Set the LDO_CORE VDD regulator level */ + ldoOption.CoreLDOVoltage = kSPC_CoreLDO_MidDriveVoltage; + ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; + (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); + } + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + + /*!< Set up dividers */ + CLOCK_SetClockDiv(kCLOCK_DivAHBCLK, 1U); /* !< Set AHBCLKDIV divider to value 1 */ + CLOCK_SetClockDiv(kCLOCK_DivFRO_HF_DIV, 1U); /* !< Set FROHFDIV divider to value 1 */ + + /* Set SystemCoreClock variable */ + SystemCoreClock = BOARD_BOOTCLOCKFRO48M_CORE_CLOCK; +} +/******************************************************************************* + ******************** Configuration BOARD_BootClockFRO64M ********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockFRO64M +outputs: +- {id: CLK_1M_clock.outFreq, value: 1 MHz} +- {id: CLK_48M_clock.outFreq, value: 48 MHz} +- {id: CPU_clock.outFreq, value: 64 MHz} +- {id: FRO_12M_clock.outFreq, value: 12 MHz} +- {id: FRO_HF_DIV_clock.outFreq, value: 64 MHz} +- {id: FRO_HF_clock.outFreq, value: 64 MHz} +- {id: MAIN_clock.outFreq, value: 64 MHz} +- {id: Slow_clock.outFreq, value: 16 MHz} +- {id: System_clock.outFreq, value: 64 MHz} +settings: +- {id: VDD_CORE, value: voltage_1v1} +- {id: MRCC.FROHFDIV.scale, value: '1', locked: true} +- {id: MRCC.OSTIMERCLKSEL.sel, value: VBAT.CLK16K_1} +- {id: SYSCON.AHBCLKDIV.scale, value: '1', locked: true} +sources: +- {id: SCG.FIRC.outFreq, value: 64 MHz} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockFRO64M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockFRO64M configuration + ******************************************************************************/ +void BOARD_BootClockFRO64M(void) +{ + uint32_t coreFreq; + spc_active_mode_core_ldo_option_t ldoOption; + spc_sram_voltage_config_t sramOption; + + /* Get the CPU Core frequency */ + coreFreq = CLOCK_GetCoreSysClkFreq(); + + /* The flow of increasing voltage and frequency */ + if (coreFreq <= BOARD_BOOTCLOCKFRO64M_CORE_CLOCK) { + /* Set the LDO_CORE VDD regulator level */ + ldoOption.CoreLDOVoltage = kSPC_CoreLDO_NormalVoltage; + ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; + (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); + /* Configure Flash to support different voltage level and frequency */ + FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x1U)); + /* Specifies the operating voltage for the SRAM's read/write timing margin */ + sramOption.operateVoltage = kSPC_sramOperateAt1P1V; + sramOption.requestVoltageUpdate = true; + (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); + } + + CLOCK_SetupFROHFClocking(64000000U); /*!< Enable FRO HF(64MHz) output */ + + CLOCK_SetupFRO12MClocking(); /*!< Setup FRO12M clock */ + + CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /* !< Switch MAIN_CLK to FRO_HF */ + + /* The flow of decreasing voltage and frequency */ + if (coreFreq > BOARD_BOOTCLOCKFRO64M_CORE_CLOCK) { + /* Configure Flash to support different voltage level and frequency */ + FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x1U)); + /* Specifies the operating voltage for the SRAM's read/write timing margin */ + sramOption.operateVoltage = kSPC_sramOperateAt1P1V; + sramOption.requestVoltageUpdate = true; + (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); + /* Set the LDO_CORE VDD regulator level */ + ldoOption.CoreLDOVoltage = kSPC_CoreLDO_NormalVoltage; + ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; + (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); + } + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + + /*!< Set up dividers */ + CLOCK_SetClockDiv(kCLOCK_DivAHBCLK, 1U); /* !< Set AHBCLKDIV divider to value 1 */ + CLOCK_SetClockDiv(kCLOCK_DivFRO_HF_DIV, 1U); /* !< Set FROHFDIV divider to value 1 */ + + /* Set SystemCoreClock variable */ + SystemCoreClock = BOARD_BOOTCLOCKFRO64M_CORE_CLOCK; +} +/******************************************************************************* + ******************** Configuration BOARD_BootClockFRO96M ********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockFRO96M +called_from_default_init: true +outputs: +- {id: CLK_1M_clock.outFreq, value: 1 MHz} +- {id: CLK_48M_clock.outFreq, value: 48 MHz} +- {id: CPU_clock.outFreq, value: 96 MHz} +- {id: FRO_12M_clock.outFreq, value: 12 MHz} +- {id: FRO_HF_DIV_clock.outFreq, value: 96 MHz} +- {id: FRO_HF_clock.outFreq, value: 96 MHz} +- {id: MAIN_clock.outFreq, value: 96 MHz} +- {id: Slow_clock.outFreq, value: 24 MHz} +- {id: System_clock.outFreq, value: 96 MHz} +settings: +- {id: VDD_CORE, value: voltage_1v1} +- {id: CLKOUTDIV_HALT, value: Enable} +- {id: MRCC.FROHFDIV.scale, value: '1', locked: true} +- {id: MRCC.OSTIMERCLKSEL.sel, value: VBAT.CLK16K_1} +- {id: SYSCON.AHBCLKDIV.scale, value: '1', locked: true} +sources: +- {id: SCG.FIRC.outFreq, value: 96 MHz} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockFRO96M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockFRO96M configuration + ******************************************************************************/ +void BOARD_BootClockFRO96M(void) +{ + uint32_t coreFreq; + spc_active_mode_core_ldo_option_t ldoOption; + spc_sram_voltage_config_t sramOption; + + /* Get the CPU Core frequency */ + coreFreq = CLOCK_GetCoreSysClkFreq(); + + /* The flow of increasing voltage and frequency */ + if (coreFreq <= BOARD_BOOTCLOCKFRO96M_CORE_CLOCK) { + /* Set the LDO_CORE VDD regulator level */ + ldoOption.CoreLDOVoltage = kSPC_CoreLDO_NormalVoltage; + ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; + (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); + /* Configure Flash to support different voltage level and frequency */ + FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x2U)); + /* Specifies the operating voltage for the SRAM's read/write timing margin */ + sramOption.operateVoltage = kSPC_sramOperateAt1P1V; + sramOption.requestVoltageUpdate = true; + (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); + } + + CLOCK_SetupFROHFClocking(96000000U); /*!< Enable FRO HF(96MHz) output */ + + CLOCK_SetupFRO12MClocking(); /*!< Setup FRO12M clock */ + + CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /* !< Switch MAIN_CLK to FRO_HF */ + + /* The flow of decreasing voltage and frequency */ + if (coreFreq > BOARD_BOOTCLOCKFRO96M_CORE_CLOCK) { + /* Configure Flash to support different voltage level and frequency */ + FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x2U)); + /* Specifies the operating voltage for the SRAM's read/write timing margin */ + sramOption.operateVoltage = kSPC_sramOperateAt1P1V; + sramOption.requestVoltageUpdate = true; + (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); + /* Set the LDO_CORE VDD regulator level */ + ldoOption.CoreLDOVoltage = kSPC_CoreLDO_NormalVoltage; + ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; + (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); + } + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + + /*!< Set up dividers */ + CLOCK_SetClockDiv(kCLOCK_DivAHBCLK, 1U); /* !< Set AHBCLKDIV divider to value 1 */ + CLOCK_SetClockDiv(kCLOCK_DivFRO_HF_DIV, 1U); /* !< Set FROHFDIV divider to value 1 */ + + /* Set SystemCoreClock variable */ + SystemCoreClock = BOARD_BOOTCLOCKFRO96M_CORE_CLOCK; +} diff --git a/hw/bsp/mcxa/boards/frdmmcxa153/clock_config.h b/hw/bsp/mcxa/boards/frdmmcxa153/clock_config.h new file mode 100644 index 000000000..079d0d312 --- /dev/null +++ b/hw/bsp/mcxa/boards/frdmmcxa153/clock_config.h @@ -0,0 +1,170 @@ +/* + * Copyright 2023 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _CLOCK_CONFIG_H_ +#define _CLOCK_CONFIG_H_ + +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes default configuration of clocks. + * + */ +void BOARD_InitBootClocks(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************** Configuration BOARD_BootClockFRO12M ********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockFRO12M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKFRO12M_CORE_CLOCK 12000000U /*!< Core clock frequency: 12000000Hz */ + + +/******************************************************************************* + * API for BOARD_BootClockFRO12M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockFRO12M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************** Configuration BOARD_BootClockFRO24M ********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockFRO24M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKFRO24M_CORE_CLOCK 24000000U /*!< Core clock frequency: 24000000Hz */ + + +/******************************************************************************* + * API for BOARD_BootClockFRO24M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockFRO24M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************** Configuration BOARD_BootClockFRO48M ********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockFRO48M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKFRO48M_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */ + + +/******************************************************************************* + * API for BOARD_BootClockFRO48M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockFRO48M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************** Configuration BOARD_BootClockFRO64M ********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockFRO64M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKFRO64M_CORE_CLOCK 64000000U /*!< Core clock frequency: 64000000Hz */ + + +/******************************************************************************* + * API for BOARD_BootClockFRO64M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockFRO64M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************** Configuration BOARD_BootClockFRO96M ********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockFRO96M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKFRO96M_CORE_CLOCK 96000000U /*!< Core clock frequency: 96000000Hz */ + + +/******************************************************************************* + * API for BOARD_BootClockFRO96M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockFRO96M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +#endif /* _CLOCK_CONFIG_H_ */ diff --git a/hw/bsp/mcxa/boards/frdmmcxa153/pin_mux.c b/hw/bsp/mcxa/boards/frdmmcxa153/pin_mux.c new file mode 100644 index 000000000..b0e6de560 --- /dev/null +++ b/hw/bsp/mcxa/boards/frdmmcxa153/pin_mux.c @@ -0,0 +1,159 @@ +/* + * Copyright 2023 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Pins v14.0 +processor: MCXA153 +package_id: MCXA153VLH +mcu_data: ksdk2_0 +processor_version: 0.14.3 +pin_labels: +- {pin_num: '38', pin_signal: P3_12/LPUART2_RTS_B/CT1_MAT2/PWM0_X0, label: LED_RED, identifier: LED_RED} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +#include "fsl_common.h" +#include "fsl_port.h" +#include "fsl_gpio.h" +#include "pin_mux.h" + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitBootPins + * Description : Calls initialization functions. + * + * END ****************************************************************************************************************/ +void BOARD_InitBootPins(void) +{ + BOARD_InitPins(); +} + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitPins: +- options: {callFromInitBoot: 'true', coreID: cm33_core0, enableClock: 'true'} +- pin_list: + - {pin_num: '38', peripheral: GPIO3, signal: 'GPIO, 12', pin_signal: P3_12/LPUART2_RTS_B/CT1_MAT2/PWM0_X0, direction: OUTPUT, gpio_init_state: 'false', slew_rate: fast, + open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, input_buffer: enable, invert_input: normal} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitPins(void) +{ + RESET_PeripheralReset(kLPUART0_RST_SHIFT_RSTn); + RESET_PeripheralReset(kPORT0_RST_SHIFT_RSTn); + CLOCK_SetClockDiv(kCLOCK_DivLPUART0, 1u); + CLOCK_AttachClk(kFRO12M_to_LPUART0); + + /* write to PORT0: Peripheral clock is enabled */ + CLOCK_EnableClock(kCLOCK_GatePORT0); + + /* Write to GPIO3: Peripheral clock is enabled */ + CLOCK_EnableClock(kCLOCK_GateGPIO3); + /* Write to PORT3: Peripheral clock is enabled */ + CLOCK_EnableClock(kCLOCK_GatePORT3); + /* GPIO3 peripheral is released from reset */ + RESET_ReleasePeripheralReset(kGPIO3_RST_SHIFT_RSTn); + /* PORT3 peripheral is released from reset */ + RESET_ReleasePeripheralReset(kPORT3_RST_SHIFT_RSTn); + + const port_pin_config_t port3_12_pin38_config = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Low internal pull resistor value is selected. */ + kPORT_LowPullResistor, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive input filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain output is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Normal drive strength is configured */ + kPORT_NormalDriveStrength, + /* Pin is configured as P3_12 */ + kPORT_MuxAlt0, + /* Digital input enabled */ + kPORT_InputBufferEnable, + /* Digital input is not inverted */ + kPORT_InputNormal, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORT3_12 (pin 38) is configured as P3_12 */ + PORT_SetPinConfig(PORT3, 12U, &port3_12_pin38_config); + + const port_pin_config_t port0_2_pin51_config = {/* Internal pull-up resistor is enabled */ + kPORT_PullUp, + /* Low internal pull resistor value is selected. */ + kPORT_LowPullResistor, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive input filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain output is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Normal drive strength is configured */ + kPORT_NormalDriveStrength, + /* Pin is configured as LPUART0_RXD */ + kPORT_MuxAlt2, + /* Digital input enabled */ + kPORT_InputBufferEnable, + /* Digital input is not inverted */ + kPORT_InputNormal, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORT0_2 (pin 51) is configured as LPUART0_RXD */ + PORT_SetPinConfig(PORT0, 2U, &port0_2_pin51_config); + + const port_pin_config_t port0_3_pin52_config = {/* Internal pull-up resistor is enabled */ + kPORT_PullUp, + /* Low internal pull resistor value is selected. */ + kPORT_LowPullResistor, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive input filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain output is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Normal drive strength is configured */ + kPORT_NormalDriveStrength, + /* Pin is configured as LPUART0_TXD */ + kPORT_MuxAlt2, + /* Digital input enabled */ + kPORT_InputBufferEnable, + /* Digital input is not inverted */ + kPORT_InputNormal, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORT0_3 (pin 52) is configured as LPUART0_TXD */ + PORT_SetPinConfig(PORT0, 3U, &port0_3_pin52_config); + +} +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/mcxa/boards/frdmmcxa153/pin_mux.h b/hw/bsp/mcxa/boards/frdmmcxa153/pin_mux.h new file mode 100644 index 000000000..06b6fdee9 --- /dev/null +++ b/hw/bsp/mcxa/boards/frdmmcxa153/pin_mux.h @@ -0,0 +1,47 @@ +/* + * Copyright 2022 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _PIN_MUX_H_ +#define _PIN_MUX_H_ + +/*! + * @addtogroup pin_mux + * @{ + */ + +/*********************************************************************************************************************** + * API + **********************************************************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Calls initialization functions. + * + */ +void BOARD_InitBootPins(void); + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitPins(void); + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ +#endif /* _PIN_MUX_H_ */ + +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/mcxa/debug.jlinkscript b/hw/bsp/mcxa/debug.jlinkscript new file mode 100644 index 000000000..fd8bcffef --- /dev/null +++ b/hw/bsp/mcxa/debug.jlinkscript @@ -0,0 +1,5 @@ +int SetupTarget(void) { + JLINK_ExecCommand("SetRTTSearchRanges 0x20000000 0x40000"); + + return 0; +} diff --git a/hw/bsp/mcxa/family.c b/hw/bsp/mcxa/family.c new file mode 100644 index 000000000..97abc1bc3 --- /dev/null +++ b/hw/bsp/mcxa/family.c @@ -0,0 +1,163 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2018, 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. + * + * This file is part of the TinyUSB stack. + */ + +#include "bsp/board_api.h" +#include "fsl_device_registers.h" +#include "fsl_gpio.h" +#include "fsl_lpuart.h" +#include "board.h" + +#include "pin_mux.h" +#include "clock_config.h" +#include "fsl_common.h" + + +#ifdef BOARD_TUD_RHPORT + #define PORT_SUPPORT_DEVICE(_n) (BOARD_TUD_RHPORT == _n) +#else + #define PORT_SUPPORT_DEVICE(_n) 0 +#endif + +#ifdef BOARD_TUH_RHPORT + #define PORT_SUPPORT_HOST(_n) (BOARD_TUH_RHPORT == _n) +#else + #define PORT_SUPPORT_HOST(_n) 0 +#endif + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM +//--------------------------------------------------------------------+ + +//--------------------------------------------------------------------+ +// Forward USB interrupt events to TinyUSB IRQ Handler +//--------------------------------------------------------------------+ +void USB0_FS_IRQHandler(void) +{ + tud_int_handler(0); +} + +void board_init(void) +{ + BOARD_InitPins(); + BOARD_InitBootClocks(); + CLOCK_SetupExtClocking(XTAL0_CLK_HZ); + + // 1ms tick timer + SysTick_Config(SystemCoreClock / 1000); + + // LED + CLOCK_EnableClock(LED_CLK); + gpio_pin_config_t LED_RED_config = { + .pinDirection = kGPIO_DigitalOutput, + .outputLogic = 0U + }; + + /* Initialize GPIO functionality on pin PIO3_12 (pin 38) */ + GPIO_PinInit(LED_GPIO, LED_PIN, &LED_RED_config); + board_led_write(1); + + // Button +#ifdef BUTTON_GPIO + CLOCK_EnableClock(BUTTON_CLK); + gpio_pin_config_t const button_config = { kGPIO_DigitalInput, 0}; + GPIO_PinInit(BUTTON_GPIO, BUTTON_PIN, &button_config); +#endif + +#ifdef UART_DEV + + CLOCK_SetClockDiv(kCLOCK_DivLPUART0, 1u); + CLOCK_AttachClk(kFRO12M_to_LPUART0); + RESET_PeripheralReset(kLPUART0_RST_SHIFT_RSTn); + + lpuart_config_t uart_config; + LPUART_GetDefaultConfig(&uart_config); + uart_config.baudRate_Bps = 115200; + uart_config.enableTx = true; + uart_config.enableRx = true; + LPUART_Init(UART_DEV, &uart_config, 12000000u); + + +#endif + + // USB VBUS + /* PORT0 PIN22 configured as USB0_VBUS */ + +#if PORT_SUPPORT_DEVICE(0) + // Port0 is Full Speed + + RESET_PeripheralReset(kUSB0_RST_SHIFT_RSTn); + CLOCK_EnableUsbfsClock(); +#endif + +} + +//--------------------------------------------------------------------+ +// 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_GPIO + return BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_GPIO, BUTTON_PIN); +#else + return 1; +#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 + LPUART_WriteBlocking(UART_DEV, (uint8_t const *) buf, 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 diff --git a/hw/bsp/mcxa/family.cmake b/hw/bsp/mcxa/family.cmake new file mode 100644 index 000000000..0aa690afc --- /dev/null +++ b/hw/bsp/mcxa/family.cmake @@ -0,0 +1,110 @@ +include_guard() + +if (NOT BOARD) + message(FATAL_ERROR "BOARD not specified") +endif () + +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-m33 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS MCXA CACHE INTERNAL "") + + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (NOT TARGET ${BOARD_TARGET}) + add_library(${BOARD_TARGET} STATIC + # external driver + #lib/sct_neopixel/sct_neopixel.c + + # driver + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_gpio.c + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_common_arm.c + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_lpuart.c + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_lpflexcomm.c + # mcu + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_reset.c + ${SDK_DIR}/devices/${MCU_VARIANT}/system_${MCU_CORE}.c + ) + # target_compile_definitions(${BOARD_TARGET} PUBLIC + # ) + target_include_directories(${BOARD_TARGET} PUBLIC + # driver + # mcu + ${CMSIS_DIR}/CMSIS/Core/Include + ${SDK_DIR}/devices/${MCU_VARIANT} + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_sources(${BOARD_TARGET} PUBLIC + ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_CORE}.S + ) + target_link_options(${BOARD_TARGET} PUBLIC + # linker file + "LINKER:--script=${SDK_DIR}/devices/${MCU_VARIANT}/gcc/${MCU_CORE}_flash.ld" + # nanolib + --specs=nosys.specs + --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () + 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_MCXA ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + # TinyUSB: Port0 is chipidea FS, Port1 is chipidea HS + ${TOP}/src/portable/chipidea/ci_fs/dcd_ci_fs.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}) + #family_flash_nxplink(${TARGET}) + #family_flash_pyocd(${TARGET}) +endfunction() diff --git a/hw/bsp/mcxa/family.mk b/hw/bsp/mcxa/family.mk new file mode 100644 index 000000000..b32282d04 --- /dev/null +++ b/hw/bsp/mcxa/family.mk @@ -0,0 +1,42 @@ +UF2_FAMILY_ID = 0x2abc77ec +SDK_DIR = hw/mcu/nxp/mcux-sdk + +DEPS_SUBMODULES += $(SDK_DIR) lib/CMSIS_5 #not found + +include $(TOP)/$(BOARD_PATH)/board.mk +CPU_CORE ?= cortex-m33 + +CFLAGS += \ + -flto \ + -DCFG_TUSB_MCU=OPT_MCU_MCXA \ + -DBOARD_TUD_RHPORT=0 + +# mcu driver cause following warnings +CFLAGS += -Wno-error=unused-parameter -Wno-error=old-style-declaration + +LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs + +# All source paths should be relative to the top level. +LD_FILE ?= $(SDK_DIR)/devices/$(MCU_VARIANT)/gcc/$(MCU_CORE)_flash.ld + +# TinyUSB: Port0 is chipidea FS, Port1 is chipidea HS +$(info "PORT0 Full Speed") +CFLAGS += -DBOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED +SRC_C += src/portable/chipidea/ci_fs/dcd_ci_fs.c + +SRC_C += \ + $(SDK_DIR)/devices/$(MCU_VARIANT)/system_$(MCU_CORE).c \ + $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_clock.c \ + $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_reset.c \ + $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_gpio.c \ + $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_lpuart.c \ + $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_common_arm.c \ + $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_spc.c +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ + $(TOP)/$(SDK_DIR)/devices/$(MCU_VARIANT) \ + $(TOP)/$(SDK_DIR)/devices/$(MCU_VARIANT)/drivers + + +SRC_S += $(SDK_DIR)/devices/$(MCU_VARIANT)/gcc/startup_$(MCU_CORE).S diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index e589c4c86..21ae3a71e 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -100,6 +100,13 @@ #define TUP_DCD_ENDPOINT_MAX 8 #define TUP_RHPORT_HIGHSPEED 1 +#elif TU_CHECK_MCU(OPT_MCU_MCXA) + // USB0 is chipidea FS + #define TUP_USBIP_CHIPIDEA_FS + #define TUP_USBIP_CHIPIDEA_FS_MCXA + + #define TUP_DCD_ENDPOINT_MAX 16 + #elif TU_CHECK_MCU(OPT_MCU_MIMXRT1XXX) #define TUP_USBIP_CHIPIDEA_HS #define TUP_USBIP_EHCI diff --git a/src/portable/chipidea/ci_fs/ci_fs_mcxa.h b/src/portable/chipidea/ci_fs/ci_fs_mcxa.h new file mode 100644 index 000000000..81786efdf --- /dev/null +++ b/src/portable/chipidea/ci_fs/ci_fs_mcxa.h @@ -0,0 +1,47 @@ +/* + * 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 _CI_FS_MCXA_H +#define _CI_FS_MCXA_H + +#include "fsl_device_registers.h" + +#define CI_FS_REG(_port) ((ci_fs_regs_t*) USB0_BASE) +#define CI_REG CI_FS_REG(0) + +void dcd_int_enable(uint8_t rhport) +{ + (void) rhport; + NVIC_EnableIRQ(USB0_IRQn); +} + +void dcd_int_disable(uint8_t rhport) +{ + (void) rhport; + NVIC_DisableIRQ(USB0_IRQn); +} + +#endif diff --git a/src/portable/chipidea/ci_fs/dcd_ci_fs.c b/src/portable/chipidea/ci_fs/dcd_ci_fs.c index 9327e09d8..08e73711f 100644 --- a/src/portable/chipidea/ci_fs/dcd_ci_fs.c +++ b/src/portable/chipidea/ci_fs/dcd_ci_fs.c @@ -35,6 +35,8 @@ #include "ci_fs_kinetis.h" #elif defined(TUP_USBIP_CHIPIDEA_FS_MCX) #include "ci_fs_mcx.h" +#elif defined(TUP_USBIP_CHIPIDEA_FS_MCXA) + #include "ci_fs_mcxa.h" #else #error "MCU is not supported" #endif diff --git a/src/tusb_option.h b/src/tusb_option.h index 767323bdd..fe9c44e96 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -175,6 +175,7 @@ // NXP LPC MCX #define OPT_MCU_MCXN9 2300 ///< NXP MCX N9 Series +#define OPT_MCU_MCXA 2301 ///< NXP MCX A Series // Check if configured MCU is one of listed // Apply _TU_CHECK_MCU with || as separator to list of input From 4d4e20b71efe8d9e1b5a141d84e058ff54801c67 Mon Sep 17 00:00:00 2001 From: IngHK Date: Thu, 8 Feb 2024 12:00:44 +0100 Subject: [PATCH 100/454] missing \r\n after TU_LOG_BUF => moved \r\n to tu_print_buf() --- src/common/tusb_debug.h | 1 + src/device/usbd.c | 1 - src/host/usbh.c | 2 -- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/common/tusb_debug.h b/src/common/tusb_debug.h index 8db1606ae..2e9f1d9cd 100644 --- a/src/common/tusb_debug.h +++ b/src/common/tusb_debug.h @@ -60,6 +60,7 @@ void tu_print_mem(void const *buf, uint32_t count, uint8_t indent); static inline void tu_print_buf(uint8_t const* buf, uint32_t bufsize) { for(uint32_t i=0; isetup->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && xfer->setup->bRequest <= TUSB_REQ_SYNCH_FRAME) ? tu_str_std_request[xfer->setup->bRequest] : "Class Request"); TU_LOG_BUF_USBH(xfer->setup, 8); - TU_LOG_USBH("\r\n"); if (xfer->complete_cb) { TU_ASSERT( hcd_setup_send(rhport, daddr, (uint8_t const*) &_ctrl_xfer.request) ); @@ -662,7 +661,6 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result if (XFER_RESULT_SUCCESS != result) { TU_LOG_USBH("[%u:%u] Control %s, xferred_bytes = %lu\r\n", rhport, dev_addr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED", xferred_bytes); TU_LOG_BUF_USBH(request, 8); - TU_LOG_USBH("\r\n"); // terminate transfer if any stage failed _xfer_complete(dev_addr, result); From b9c6b22165ce1912ec40b808570e13756e8faf4e Mon Sep 17 00:00:00 2001 From: Jerry Palacios Date: Thu, 8 Feb 2024 11:10:10 -0600 Subject: [PATCH 101/454] cortex m33+nodsp+nofpu make file created --- .../make/cpu/cortex-m33-nodsp-nofp.mk | 18 ++++++++++++++++++ hw/bsp/mcxa/boards/frdmmcxa153/board.mk | 13 ------------- hw/bsp/mcxa/family.mk | 2 +- 3 files changed, 19 insertions(+), 14 deletions(-) create mode 100644 examples/build_system/make/cpu/cortex-m33-nodsp-nofp.mk diff --git a/examples/build_system/make/cpu/cortex-m33-nodsp-nofp.mk b/examples/build_system/make/cpu/cortex-m33-nodsp-nofp.mk new file mode 100644 index 000000000..0a2f99ab0 --- /dev/null +++ b/examples/build_system/make/cpu/cortex-m33-nodsp-nofp.mk @@ -0,0 +1,18 @@ +ifeq ($(TOOLCHAIN),gcc) + CFLAGS += \ + -mthumb \ + -mcpu=cortex-m33+nodsp \ + -mfloat-abi=soft \ + +#else ifeq ($(TOOLCHAIN),iar) +# CFLAGS += \ +# --cpu cortex-m33 \ +# --fpu VFPv5-SP \ +# +# ASFLAGS += \ +# --cpu cortex-m33 \ +# --fpu VFPv5-SP \ +# +endif +# +FREERTOS_PORTABLE_SRC ?= $(FREERTOS_PORTABLE_PATH)/ARM_CM33_NTZ/non_secure \ No newline at end of file diff --git a/hw/bsp/mcxa/boards/frdmmcxa153/board.mk b/hw/bsp/mcxa/boards/frdmmcxa153/board.mk index e8797cd95..18f7e3cb5 100644 --- a/hw/bsp/mcxa/boards/frdmmcxa153/board.mk +++ b/hw/bsp/mcxa/boards/frdmmcxa153/board.mk @@ -4,19 +4,6 @@ PORT = 0 CFLAGS += \ -DCPU_MCXA153VLH \ - -DCPU_MCXA153VLH_cm33_nodsp \ - -DPRINTF_FLOAT_ENABLE=0 \ - -DSCANF_FLOAT_ENABLE=0 \ - -DPRINTF_ADVANCED_ENABLE=0 \ - -DSCANF_ADVANCED_ENABLE=0 \ - -mcpu=cortex-m33+nodsp+nofp+nosimd - -#FORCING NOT TO USE DPS AND FPU UNITS (THIS CHIP DOESN'T HAVE) -CFLAGS += -D__SOFTFP__ -# Undefine __ARM_FEATURE_DSP if it's already defined -CFLAGS += -U__ARM_FEATURE_DSP -# Define __ARM_FEATURE_DSP with the new value -CFLAGS += -D__ARM_FEATURE_DSP=0 JLINK_DEVICE = MCXA153 diff --git a/hw/bsp/mcxa/family.mk b/hw/bsp/mcxa/family.mk index b32282d04..87ae92fab 100644 --- a/hw/bsp/mcxa/family.mk +++ b/hw/bsp/mcxa/family.mk @@ -4,7 +4,7 @@ SDK_DIR = hw/mcu/nxp/mcux-sdk DEPS_SUBMODULES += $(SDK_DIR) lib/CMSIS_5 #not found include $(TOP)/$(BOARD_PATH)/board.mk -CPU_CORE ?= cortex-m33 +CPU_CORE ?= cortex-m33-nodsp-nofp CFLAGS += \ -flto \ From fa4314e0cefab8c46640ad5bf2a21eb59668449f Mon Sep 17 00:00:00 2001 From: Jerry Palacios Date: Thu, 8 Feb 2024 11:55:01 -0600 Subject: [PATCH 102/454] button commented --- hw/bsp/mcxa/boards/frdmmcxa153/board.h | 8 ++++---- hw/bsp/mcxa/family.c | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/hw/bsp/mcxa/boards/frdmmcxa153/board.h b/hw/bsp/mcxa/boards/frdmmcxa153/board.h index d18175c3d..8ebabb328 100644 --- a/hw/bsp/mcxa/boards/frdmmcxa153/board.h +++ b/hw/bsp/mcxa/boards/frdmmcxa153/board.h @@ -38,10 +38,10 @@ #define LED_STATE_ON 0 // WAKE button (Dummy, use unused pin -#define BUTTON_GPIO GPIO1 -#define BUTTON_CLK kCLOCK_GateGPIO1 -#define BUTTON_PIN 7 //sw3 -#define BUTTON_STATE_ACTIVE 0 +// #define BUTTON_GPIO GPIO1 +// #define BUTTON_CLK kCLOCK_GateGPIO1 +// #define BUTTON_PIN 7 //sw3 +// #define BUTTON_STATE_ACTIVE 0 // UART #define UART_DEV LPUART0 diff --git a/hw/bsp/mcxa/family.c b/hw/bsp/mcxa/family.c index 97abc1bc3..78b1676d4 100644 --- a/hw/bsp/mcxa/family.c +++ b/hw/bsp/mcxa/family.c @@ -80,11 +80,11 @@ void board_init(void) board_led_write(1); // Button -#ifdef BUTTON_GPIO - CLOCK_EnableClock(BUTTON_CLK); - gpio_pin_config_t const button_config = { kGPIO_DigitalInput, 0}; - GPIO_PinInit(BUTTON_GPIO, BUTTON_PIN, &button_config); -#endif +//#ifdef BUTTON_GPIO +// CLOCK_EnableClock(BUTTON_CLK); +// gpio_pin_config_t const button_config = { kGPIO_DigitalInput, 0}; +// GPIO_PinInit(BUTTON_GPIO, BUTTON_PIN, &button_config); +//#endif #ifdef UART_DEV From 2c766c4dafa6c44f5c29f833443e13ca9b5c1f90 Mon Sep 17 00:00:00 2001 From: Jerry Palacios Date: Thu, 8 Feb 2024 12:43:13 -0600 Subject: [PATCH 103/454] Update family.c --- hw/bsp/mcxa/family.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/hw/bsp/mcxa/family.c b/hw/bsp/mcxa/family.c index 78b1676d4..670542892 100644 --- a/hw/bsp/mcxa/family.c +++ b/hw/bsp/mcxa/family.c @@ -32,7 +32,6 @@ #include "pin_mux.h" #include "clock_config.h" -#include "fsl_common.h" #ifdef BOARD_TUD_RHPORT @@ -80,11 +79,11 @@ void board_init(void) board_led_write(1); // Button -//#ifdef BUTTON_GPIO -// CLOCK_EnableClock(BUTTON_CLK); -// gpio_pin_config_t const button_config = { kGPIO_DigitalInput, 0}; -// GPIO_PinInit(BUTTON_GPIO, BUTTON_PIN, &button_config); -//#endif +#ifdef BUTTON_GPIO + CLOCK_EnableClock(BUTTON_CLK); + gpio_pin_config_t const button_config = { kGPIO_DigitalInput, 0}; + GPIO_PinInit(BUTTON_GPIO, BUTTON_PIN, &button_config); +#endif #ifdef UART_DEV @@ -107,7 +106,8 @@ void board_init(void) #if PORT_SUPPORT_DEVICE(0) // Port0 is Full Speed - + //CLOCK_EnableClock(kCLOCK_Usb0Ram); + //CLOCK_EnableClock(kCLOCK_Usb0Fs); RESET_PeripheralReset(kUSB0_RST_SHIFT_RSTn); CLOCK_EnableUsbfsClock(); #endif From 5b762e189ce1ab50a861d65895a41486b098cce8 Mon Sep 17 00:00:00 2001 From: Jerry Palacios Date: Thu, 8 Feb 2024 16:25:41 -0600 Subject: [PATCH 104/454] uart rx disabled --- hw/bsp/mcxa/family.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hw/bsp/mcxa/family.c b/hw/bsp/mcxa/family.c index 670542892..9796fbb74 100644 --- a/hw/bsp/mcxa/family.c +++ b/hw/bsp/mcxa/family.c @@ -95,7 +95,7 @@ void board_init(void) LPUART_GetDefaultConfig(&uart_config); uart_config.baudRate_Bps = 115200; uart_config.enableTx = true; - uart_config.enableRx = true; + uart_config.enableRx = false; LPUART_Init(UART_DEV, &uart_config, 12000000u); @@ -161,3 +161,4 @@ uint32_t board_millis(void) return system_ticks; } #endif + \ No newline at end of file From 7369d1f36e91907e9d5be516b207c94cf8e2ad0f Mon Sep 17 00:00:00 2001 From: Jerry Palacios Date: Fri, 9 Feb 2024 08:51:37 -0600 Subject: [PATCH 105/454] Update family.c --- hw/bsp/mcxa/family.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/bsp/mcxa/family.c b/hw/bsp/mcxa/family.c index 9796fbb74..1aa364e8a 100644 --- a/hw/bsp/mcxa/family.c +++ b/hw/bsp/mcxa/family.c @@ -53,7 +53,7 @@ //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ -void USB0_FS_IRQHandler(void) +void USB0_IRQHandler(void) { tud_int_handler(0); } From 73122cd5f90d3516474e89f30ee8e2266d03d5d8 Mon Sep 17 00:00:00 2001 From: Jerry Palacios Date: Fri, 9 Feb 2024 09:36:58 -0600 Subject: [PATCH 106/454] mcx family renamed as mcxn MCXN and MCXA have different ARM Cortex M33 core, can't be on the same family --- hw/bsp/{mcx => mcxn}/FreeRTOSConfig/FreeRTOSConfig.h | 0 hw/bsp/{mcx => mcxn}/boards/frdmmcxn947/board.cmake | 0 hw/bsp/{mcx => mcxn}/boards/frdmmcxn947/board.h | 0 hw/bsp/{mcx => mcxn}/boards/frdmmcxn947/board.mk | 0 hw/bsp/{mcx => mcxn}/boards/frdmmcxn947/clock_config.c | 0 hw/bsp/{mcx => mcxn}/boards/frdmmcxn947/clock_config.h | 0 hw/bsp/{mcx => mcxn}/boards/frdmmcxn947/pin_mux.c | 0 hw/bsp/{mcx => mcxn}/boards/frdmmcxn947/pin_mux.h | 0 hw/bsp/{mcx => mcxn}/boards/mcxn947brk/board.cmake | 0 hw/bsp/{mcx => mcxn}/boards/mcxn947brk/board.h | 0 hw/bsp/{mcx => mcxn}/boards/mcxn947brk/board.mk | 0 hw/bsp/{mcx => mcxn}/boards/mcxn947brk/clock_config.c | 0 hw/bsp/{mcx => mcxn}/boards/mcxn947brk/clock_config.h | 0 hw/bsp/{mcx => mcxn}/boards/mcxn947brk/pin_mux.c | 0 hw/bsp/{mcx => mcxn}/boards/mcxn947brk/pin_mux.h | 0 hw/bsp/{mcx => mcxn}/debug.jlinkscript | 0 hw/bsp/{mcx => mcxn}/family.c | 0 hw/bsp/{mcx => mcxn}/family.cmake | 0 hw/bsp/{mcx => mcxn}/family.mk | 0 tools/get_deps.py | 4 ++-- 20 files changed, 2 insertions(+), 2 deletions(-) rename hw/bsp/{mcx => mcxn}/FreeRTOSConfig/FreeRTOSConfig.h (100%) rename hw/bsp/{mcx => mcxn}/boards/frdmmcxn947/board.cmake (100%) rename hw/bsp/{mcx => mcxn}/boards/frdmmcxn947/board.h (100%) rename hw/bsp/{mcx => mcxn}/boards/frdmmcxn947/board.mk (100%) rename hw/bsp/{mcx => mcxn}/boards/frdmmcxn947/clock_config.c (100%) rename hw/bsp/{mcx => mcxn}/boards/frdmmcxn947/clock_config.h (100%) rename hw/bsp/{mcx => mcxn}/boards/frdmmcxn947/pin_mux.c (100%) rename hw/bsp/{mcx => mcxn}/boards/frdmmcxn947/pin_mux.h (100%) rename hw/bsp/{mcx => mcxn}/boards/mcxn947brk/board.cmake (100%) rename hw/bsp/{mcx => mcxn}/boards/mcxn947brk/board.h (100%) rename hw/bsp/{mcx => mcxn}/boards/mcxn947brk/board.mk (100%) rename hw/bsp/{mcx => mcxn}/boards/mcxn947brk/clock_config.c (100%) rename hw/bsp/{mcx => mcxn}/boards/mcxn947brk/clock_config.h (100%) rename hw/bsp/{mcx => mcxn}/boards/mcxn947brk/pin_mux.c (100%) rename hw/bsp/{mcx => mcxn}/boards/mcxn947brk/pin_mux.h (100%) rename hw/bsp/{mcx => mcxn}/debug.jlinkscript (100%) rename hw/bsp/{mcx => mcxn}/family.c (100%) rename hw/bsp/{mcx => mcxn}/family.cmake (100%) rename hw/bsp/{mcx => mcxn}/family.mk (100%) diff --git a/hw/bsp/mcx/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/mcxn/FreeRTOSConfig/FreeRTOSConfig.h similarity index 100% rename from hw/bsp/mcx/FreeRTOSConfig/FreeRTOSConfig.h rename to hw/bsp/mcxn/FreeRTOSConfig/FreeRTOSConfig.h diff --git a/hw/bsp/mcx/boards/frdmmcxn947/board.cmake b/hw/bsp/mcxn/boards/frdmmcxn947/board.cmake similarity index 100% rename from hw/bsp/mcx/boards/frdmmcxn947/board.cmake rename to hw/bsp/mcxn/boards/frdmmcxn947/board.cmake diff --git a/hw/bsp/mcx/boards/frdmmcxn947/board.h b/hw/bsp/mcxn/boards/frdmmcxn947/board.h similarity index 100% rename from hw/bsp/mcx/boards/frdmmcxn947/board.h rename to hw/bsp/mcxn/boards/frdmmcxn947/board.h diff --git a/hw/bsp/mcx/boards/frdmmcxn947/board.mk b/hw/bsp/mcxn/boards/frdmmcxn947/board.mk similarity index 100% rename from hw/bsp/mcx/boards/frdmmcxn947/board.mk rename to hw/bsp/mcxn/boards/frdmmcxn947/board.mk diff --git a/hw/bsp/mcx/boards/frdmmcxn947/clock_config.c b/hw/bsp/mcxn/boards/frdmmcxn947/clock_config.c similarity index 100% rename from hw/bsp/mcx/boards/frdmmcxn947/clock_config.c rename to hw/bsp/mcxn/boards/frdmmcxn947/clock_config.c diff --git a/hw/bsp/mcx/boards/frdmmcxn947/clock_config.h b/hw/bsp/mcxn/boards/frdmmcxn947/clock_config.h similarity index 100% rename from hw/bsp/mcx/boards/frdmmcxn947/clock_config.h rename to hw/bsp/mcxn/boards/frdmmcxn947/clock_config.h diff --git a/hw/bsp/mcx/boards/frdmmcxn947/pin_mux.c b/hw/bsp/mcxn/boards/frdmmcxn947/pin_mux.c similarity index 100% rename from hw/bsp/mcx/boards/frdmmcxn947/pin_mux.c rename to hw/bsp/mcxn/boards/frdmmcxn947/pin_mux.c diff --git a/hw/bsp/mcx/boards/frdmmcxn947/pin_mux.h b/hw/bsp/mcxn/boards/frdmmcxn947/pin_mux.h similarity index 100% rename from hw/bsp/mcx/boards/frdmmcxn947/pin_mux.h rename to hw/bsp/mcxn/boards/frdmmcxn947/pin_mux.h diff --git a/hw/bsp/mcx/boards/mcxn947brk/board.cmake b/hw/bsp/mcxn/boards/mcxn947brk/board.cmake similarity index 100% rename from hw/bsp/mcx/boards/mcxn947brk/board.cmake rename to hw/bsp/mcxn/boards/mcxn947brk/board.cmake diff --git a/hw/bsp/mcx/boards/mcxn947brk/board.h b/hw/bsp/mcxn/boards/mcxn947brk/board.h similarity index 100% rename from hw/bsp/mcx/boards/mcxn947brk/board.h rename to hw/bsp/mcxn/boards/mcxn947brk/board.h diff --git a/hw/bsp/mcx/boards/mcxn947brk/board.mk b/hw/bsp/mcxn/boards/mcxn947brk/board.mk similarity index 100% rename from hw/bsp/mcx/boards/mcxn947brk/board.mk rename to hw/bsp/mcxn/boards/mcxn947brk/board.mk diff --git a/hw/bsp/mcx/boards/mcxn947brk/clock_config.c b/hw/bsp/mcxn/boards/mcxn947brk/clock_config.c similarity index 100% rename from hw/bsp/mcx/boards/mcxn947brk/clock_config.c rename to hw/bsp/mcxn/boards/mcxn947brk/clock_config.c diff --git a/hw/bsp/mcx/boards/mcxn947brk/clock_config.h b/hw/bsp/mcxn/boards/mcxn947brk/clock_config.h similarity index 100% rename from hw/bsp/mcx/boards/mcxn947brk/clock_config.h rename to hw/bsp/mcxn/boards/mcxn947brk/clock_config.h diff --git a/hw/bsp/mcx/boards/mcxn947brk/pin_mux.c b/hw/bsp/mcxn/boards/mcxn947brk/pin_mux.c similarity index 100% rename from hw/bsp/mcx/boards/mcxn947brk/pin_mux.c rename to hw/bsp/mcxn/boards/mcxn947brk/pin_mux.c diff --git a/hw/bsp/mcx/boards/mcxn947brk/pin_mux.h b/hw/bsp/mcxn/boards/mcxn947brk/pin_mux.h similarity index 100% rename from hw/bsp/mcx/boards/mcxn947brk/pin_mux.h rename to hw/bsp/mcxn/boards/mcxn947brk/pin_mux.h diff --git a/hw/bsp/mcx/debug.jlinkscript b/hw/bsp/mcxn/debug.jlinkscript similarity index 100% rename from hw/bsp/mcx/debug.jlinkscript rename to hw/bsp/mcxn/debug.jlinkscript diff --git a/hw/bsp/mcx/family.c b/hw/bsp/mcxn/family.c similarity index 100% rename from hw/bsp/mcx/family.c rename to hw/bsp/mcxn/family.c diff --git a/hw/bsp/mcx/family.cmake b/hw/bsp/mcxn/family.cmake similarity index 100% rename from hw/bsp/mcx/family.cmake rename to hw/bsp/mcxn/family.cmake diff --git a/hw/bsp/mcx/family.mk b/hw/bsp/mcxn/family.mk similarity index 100% rename from hw/bsp/mcx/family.mk rename to hw/bsp/mcxn/family.mk diff --git a/tools/get_deps.py b/tools/get_deps.py index ef83beea9..2a14c6123 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -52,7 +52,7 @@ deps_optional = { 'lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43'], 'hw/mcu/nxp/mcux-sdk': ['https://github.com/wavenumber-eng/mcux-sdk.git', 'main', - 'kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx mcxa imxrt'], + 'kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcxn mcxa imxrt'], 'hw/mcu/raspberry_pi/Pico-PIO-USB': ['https://github.com/sekigon-gonnoc/Pico-PIO-USB.git', '0f747aaa0c16f750bdfa2ba37ec25d6c8e1bc117', 'rp2040'], @@ -175,7 +175,7 @@ deps_optional = { 'ch32f20x'], '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 saml2x' + 'imxrt kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcxn mcxa mm32 msp432e4 nrf ra saml2x' 'stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h5' 'stm32h7 stm32l0 stm32l1 stm32l4 stm32l5 stm32u5 stm32wb'], 'lib/sct_neopixel': ['https://github.com/gsteiert/sct_neopixel.git', From b44cae8f182408031290268ca7b42f3c77665225 Mon Sep 17 00:00:00 2001 From: Jerry Palacios Date: Fri, 9 Feb 2024 11:07:51 -0600 Subject: [PATCH 107/454] frdmmcxa153 now working with cmake+ninja --- .../cmake/cpu/cortex-m33-nodsp-nofp.cmake | 17 +++++++++++++++++ .../make/cpu/cortex-m33-nodsp-nofp.mk | 18 ++++++++---------- hw/bsp/mcxa/family.cmake | 4 ++-- 3 files changed, 27 insertions(+), 12 deletions(-) create mode 100644 examples/build_system/cmake/cpu/cortex-m33-nodsp-nofp.cmake diff --git a/examples/build_system/cmake/cpu/cortex-m33-nodsp-nofp.cmake b/examples/build_system/cmake/cpu/cortex-m33-nodsp-nofp.cmake new file mode 100644 index 000000000..7946affbe --- /dev/null +++ b/examples/build_system/cmake/cpu/cortex-m33-nodsp-nofp.cmake @@ -0,0 +1,17 @@ +if (TOOLCHAIN STREQUAL "gcc") + set(TOOLCHAIN_COMMON_FLAGS + -mthumb + -mcpu=cortex-m33+nodsp + -mfloat-abi=soft + ) + + set(FREERTOS_PORT GCC_ARM_CM33_NTZ_NONSECURE CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "iar") + set(TOOLCHAIN_COMMON_FLAGS + --cpu cortex-m33+nodsp + ) + + set(FREERTOS_PORT IAR_ARM_CM4F CACHE INTERNAL "") + +endif () diff --git a/examples/build_system/make/cpu/cortex-m33-nodsp-nofp.mk b/examples/build_system/make/cpu/cortex-m33-nodsp-nofp.mk index 0a2f99ab0..f74f46d54 100644 --- a/examples/build_system/make/cpu/cortex-m33-nodsp-nofp.mk +++ b/examples/build_system/make/cpu/cortex-m33-nodsp-nofp.mk @@ -4,15 +4,13 @@ ifeq ($(TOOLCHAIN),gcc) -mcpu=cortex-m33+nodsp \ -mfloat-abi=soft \ -#else ifeq ($(TOOLCHAIN),iar) -# CFLAGS += \ -# --cpu cortex-m33 \ -# --fpu VFPv5-SP \ -# -# ASFLAGS += \ -# --cpu cortex-m33 \ -# --fpu VFPv5-SP \ -# +else ifeq ($(TOOLCHAIN),iar) + CFLAGS += \ + --cpu cortex-m33+nodsp \ + + ASFLAGS += \ + --cpu cortex-m33+nodsp \ + endif -# + FREERTOS_PORTABLE_SRC ?= $(FREERTOS_PORTABLE_PATH)/ARM_CM33_NTZ/non_secure \ No newline at end of file diff --git a/hw/bsp/mcxa/family.cmake b/hw/bsp/mcxa/family.cmake index 0aa690afc..d2b2321d6 100644 --- a/hw/bsp/mcxa/family.cmake +++ b/hw/bsp/mcxa/family.cmake @@ -11,7 +11,7 @@ set(CMSIS_DIR ${TOP}/lib/CMSIS_5) include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up -set(CMAKE_SYSTEM_PROCESSOR cortex-m33 CACHE INTERNAL "System Processor") +set(CMAKE_SYSTEM_PROCESSOR cortex-m33-nodsp-nofp CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS MCXA CACHE INTERNAL "") @@ -31,7 +31,7 @@ function(add_board_target BOARD_TARGET) ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_gpio.c ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_common_arm.c ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_lpuart.c - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_lpflexcomm.c + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_spc.c # mcu ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_reset.c From 7e0100408d9ea1b0f3e8c46d69b925a66694d66a Mon Sep 17 00:00:00 2001 From: Jerry Palacios Date: Fri, 9 Feb 2024 11:15:26 -0600 Subject: [PATCH 108/454] MCX modified to MCXA and MCXN --- README.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index fe2417451..c48007c23 100644 --- a/README.rst +++ b/README.rst @@ -139,7 +139,9 @@ Following CPUs are supported, check out `Supported Devices`_ for comprehensive l | +---------+--------------------------------------------------+ | | LPC | 11u, 13, 15, 17, 18, 40, 43, 51u, 54, 55 | | +---------+--------------------------------------------------+ -| | MCX | N9 | +| | MCXA | A153 | +| +---------+--------------------------------------------------+ +| | MCXN | N9 | +--------------+---------+--------------------------------------------------+ | Raspberry Pi | RP2040 | +--------------+-----+------------------------------------------------------+ From 68bb85840639b2a3d8c4ad51e31245bd039e5b9f Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Mon, 12 Feb 2024 16:12:32 +0100 Subject: [PATCH 109/454] nrf5x: Handle ISOOUT CRC errors NRF5x USB controller can detect ISO OUT CRC errors. In such case USBEVENT is signaled with EVENTCAUSE_ISOOUTCRC set. Even if controller detects corrupted ISO OUT packet it allows to data transfer from ednpoint to RAM however packet is corrupted and code could just as well drop packet altogether. With current implementation incoming ISO OUT packets were put in FIFO and exact information how much data already in FIFO is correct was hard to keep track of. If was observed that on certain configurations HS hub when FS device was connected occasionally sent invalid (short) packet. In such case if packet length was reported odd audio stream was not recognizable any more. With this change corrupted packets are not passed to upper layers and are silently dropped. --- src/portable/nordic/nrf5x/dcd_nrf5x.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index 4e702aed4..841cda752 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -653,7 +653,11 @@ void dcd_int_handler(uint8_t rhport) if (NRF_USBD->EPOUTEN & USBD_EPOUTEN_ISOOUT_Msk) { iso_enabled = true; - xact_out_dma(EP_ISO_NUM); + // Transfer from endpoint to RAM only if data is not corrupted + if ((int_status & USBD_INTEN_USBEVENT_Msk) == 0 || + (NRF_USBD->EVENTCAUSE & USBD_EVENTCAUSE_ISOOUTCRC_Msk) == 0) { + xact_out_dma(EP_ISO_NUM); + } } // ISOIN: Notify client that data was transferred @@ -683,7 +687,7 @@ void dcd_int_handler(uint8_t rhport) { TU_LOG(2, "EVENTCAUSE = 0x%04lX\r\n", NRF_USBD->EVENTCAUSE); - enum { EVT_CAUSE_MASK = USBD_EVENTCAUSE_SUSPEND_Msk | USBD_EVENTCAUSE_RESUME_Msk | USBD_EVENTCAUSE_USBWUALLOWED_Msk }; + enum { EVT_CAUSE_MASK = USBD_EVENTCAUSE_SUSPEND_Msk | USBD_EVENTCAUSE_RESUME_Msk | USBD_EVENTCAUSE_USBWUALLOWED_Msk | USBD_EVENTCAUSE_ISOOUTCRC_Msk }; uint32_t const evt_cause = NRF_USBD->EVENTCAUSE & EVT_CAUSE_MASK; NRF_USBD->EVENTCAUSE = evt_cause; // clear interrupt From 7b780c068cb7eadafd316e142bcb8e7baf0511f9 Mon Sep 17 00:00:00 2001 From: Jerry Palacios Date: Mon, 12 Feb 2024 09:29:10 -0600 Subject: [PATCH 110/454] Button modification --- hw/bsp/mcxa/boards/frdmmcxa153/board.h | 10 +++++----- hw/bsp/mcxa/family.c | 3 --- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/hw/bsp/mcxa/boards/frdmmcxa153/board.h b/hw/bsp/mcxa/boards/frdmmcxa153/board.h index 8ebabb328..02a452da5 100644 --- a/hw/bsp/mcxa/boards/frdmmcxa153/board.h +++ b/hw/bsp/mcxa/boards/frdmmcxa153/board.h @@ -37,11 +37,11 @@ #define LED_PIN 12 // red #define LED_STATE_ON 0 -// WAKE button (Dummy, use unused pin -// #define BUTTON_GPIO GPIO1 -// #define BUTTON_CLK kCLOCK_GateGPIO1 -// #define BUTTON_PIN 7 //sw3 -// #define BUTTON_STATE_ACTIVE 0 +// ISP button (Dummy, use unused pin + #define BUTTON_GPIO GPIO3 + #define BUTTON_CLK kCLOCK_GateGPIO3 + #define BUTTON_PIN 29 //sw2 + #define BUTTON_STATE_ACTIVE 0 // UART #define UART_DEV LPUART0 diff --git a/hw/bsp/mcxa/family.c b/hw/bsp/mcxa/family.c index 1aa364e8a..d2bc35f8c 100644 --- a/hw/bsp/mcxa/family.c +++ b/hw/bsp/mcxa/family.c @@ -105,9 +105,6 @@ void board_init(void) /* PORT0 PIN22 configured as USB0_VBUS */ #if PORT_SUPPORT_DEVICE(0) - // Port0 is Full Speed - //CLOCK_EnableClock(kCLOCK_Usb0Ram); - //CLOCK_EnableClock(kCLOCK_Usb0Fs); RESET_PeripheralReset(kUSB0_RST_SHIFT_RSTn); CLOCK_EnableUsbfsClock(); #endif From 79aecf3fb7d6a384eb745253d11a95d657469eed Mon Sep 17 00:00:00 2001 From: IngHK Date: Wed, 14 Feb 2024 09:16:18 +0100 Subject: [PATCH 111/454] fixed #2469 --- src/common/tusb_fifo.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index d6c3db4ce..76696396b 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -224,6 +224,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; + default: break; } } From 5ca99800604ec3ed9d45bf4660db04101aa737ce Mon Sep 17 00:00:00 2001 From: Chris Desjardins Date: Thu, 15 Feb 2024 16:27:49 +0100 Subject: [PATCH 112/454] Do not enable the Mode mismatch interrupt source, it is not cleared If this interrupt ever hits it will result in an infinite interrupt loop as it is never cleared. --- src/portable/synopsys/dwc2/dcd_dwc2.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 3e15d51c6..3f00243e5 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -462,9 +462,7 @@ void dcd_init(uint8_t rhport) { dwc2->gotgint |= int_mask; // Required as part of core initialization. - // TODO: How should mode mismatch be handled? It will cause - // the core to stop working/require reset. - dwc2->gintmsk = GINTMSK_OTGINT | GINTMSK_MMISM | GINTMSK_RXFLVLM | + dwc2->gintmsk = GINTMSK_OTGINT | GINTMSK_RXFLVLM | GINTMSK_USBSUSPM | GINTMSK_USBRST | GINTMSK_ENUMDNEM | GINTMSK_WUIM; // Enable global interrupt From 27c125416a60986c4bce670097efbd88744fab9b Mon Sep 17 00:00:00 2001 From: Kai <60053077+kaidegit@users.noreply.github.com> Date: Fri, 16 Feb 2024 15:16:17 +0800 Subject: [PATCH 113/454] use rt-thread 5+ mq recv api --- src/osal/osal_rtthread.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/osal/osal_rtthread.h b/src/osal/osal_rtthread.h index 18eb9c693..d03b53bee 100644 --- a/src/osal/osal_rtthread.h +++ b/src/osal/osal_rtthread.h @@ -2,6 +2,7 @@ * The MIT License (MIT) * * Copyright (c) 2020 tfx2001 (2479727366@qq.com) + * Copyright (c) 2020 yekai (2857693944@qq.com) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -111,9 +112,12 @@ TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_de } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void *data, uint32_t msec) { - rt_tick_t tick = rt_tick_from_millisecond((rt_int32_t) msec); +#if RT_VERSION_MAJOR >= 5 + return rt_mq_recv(qhdl, data, qhdl->msg_size, tick) > 0; +#else return rt_mq_recv(qhdl, data, qhdl->msg_size, tick) == RT_EOK; +#endif /* RT_VERSION_MAJOR >= 5 */ } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const *data, bool in_isr) { From e9dc8f3e7dc6799ad674139df97e253acc71f4d7 Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Mon, 19 Feb 2024 18:12:03 +0700 Subject: [PATCH 114/454] fix wrong volatile usage in ohci gtd --- src/portable/ohci/ohci.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/portable/ohci/ohci.h b/src/portable/ohci/ohci.h index 4feefd771..94bad5df7 100644 --- a/src/portable/ohci/ohci.h +++ b/src/portable/ohci/ohci.h @@ -83,7 +83,7 @@ typedef struct TU_ATTR_ALIGNED(16) volatile uint32_t condition_code : 4; // Word 1 - volatile uint8_t* current_buffer_pointer; + uint8_t* volatile current_buffer_pointer; // Word 2 : next TD volatile uint32_t next; From e361b1a9bad60ebf3118c69e58b259964ae90a31 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 19 Feb 2024 18:45:03 +0700 Subject: [PATCH 115/454] add clock_config.c/h from mcux to frdmk32l2a4 and frdm_k32l2b --- .../boards/frdm_k32l2a4s/board.mk | 3 - .../boards/frdm_k32l2a4s/clock_config.c | 491 ++++++++++++++++++ .../boards/frdm_k32l2a4s/clock_config.h | 164 ++++++ .../kinetis_k32l2/boards/frdm_k32l2b/board.mk | 3 - .../boards/frdm_k32l2b/clock_config.c | 220 ++++++++ .../boards/frdm_k32l2b/clock_config.h | 110 ++++ 6 files changed, 985 insertions(+), 6 deletions(-) create mode 100644 hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/clock_config.c create mode 100644 hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/clock_config.h create mode 100644 hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.c create mode 100644 hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.h diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/board.mk b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/board.mk index f69700139..c4dc65b63 100644 --- a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/board.mk +++ b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/board.mk @@ -8,9 +8,6 @@ CFLAGS += -Wno-error=unused-parameter -Wno-error=redundant-decls -Wno-error=cast # All source paths should be relative to the top level. LD_FILE = $(MCU_DIR)/gcc/K32L2A41xxxxA_flash.ld -SRC_C += \ - $(MCU_DIR)/project_template/clock_config.c \ - # For flash-jlink target JLINK_DEVICE = K32L2A41xxxxA diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/clock_config.c b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/clock_config.c new file mode 100644 index 000000000..2814efc86 --- /dev/null +++ b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/clock_config.c @@ -0,0 +1,491 @@ +/* + * Copyright 2019 ,2021 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ +/* + * How to setup clock using clock driver functions: + * + * 1. Call CLOCK_InitXXX() to configure corresponding SCG clock source. + * Note: The clock could not be set when it is being used as system clock. + * In default out of reset, the CPU is clocked from FIRC(IRC48M), + * so before setting FIRC, change to use another available clock source. + * + * 2. Call CLOCK_SetXtal0Freq() to set XTAL0 frequency based on board settings. + * + * 3. Call CLOCK_SetXxxModeSysClkConfig() to set SCG mode for Xxx run mode. + * Wait until the system clock source is changed to target source. + * + * 4. If power mode change is needed, call SMC_SetPowerModeProtection() to allow + * corresponding power mode and SMC_SetPowerModeXxx() to change to Xxx mode. + * Supported run mode and clock restrictions could be found in Reference Manual. + */ + +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Clocks v7.0 +processor: K32L2A41xxxxA +package_id: K32L2A41VLL1A +mcu_data: ksdk2_0 +processor_version: 9.0.0 + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +#include "fsl_smc.h" +#include "clock_config.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define SCG_CLKOUTCNFG_SIRC 2U /*!< SCG CLKOUT clock select: Slow IRC */ +#define SCG_SOSC_DISABLE 0U /*!< System OSC disabled */ +#define SCG_SPLL_DISABLE 0U /*!< System PLL disabled */ +#define SCG_SYS_OSC_CAP_0P 0U /*!< Oscillator 0pF capacitor load */ + +/******************************************************************************* + * Variables + ******************************************************************************/ +/* System clock frequency. */ +extern uint32_t SystemCoreClock; + +/******************************************************************************* + * Code + ******************************************************************************/ +/*FUNCTION********************************************************************** + * + * Function Name : CLOCK_CONFIG_SetScgOutSel + * Description : Set the SCG clock out select (CLKOUTSEL). + * Param setting : The selected clock source. + * + *END**************************************************************************/ +static void CLOCK_CONFIG_SetScgOutSel(uint8_t setting) +{ + SCG->CLKOUTCNFG = SCG_CLKOUTCNFG_CLKOUTSEL(setting); +} + +/*FUNCTION********************************************************************** + * + * Function Name : CLOCK_CONFIG_FircSafeConfig + * Description : This function is used to safely configure FIRC clock. + * In default out of reset, the CPU is clocked from FIRC(IRC48M). + * Before setting FIRC, change to use SIRC as system clock, + * then configure FIRC. After FIRC is set, change back to use FIRC + * in case SIRC need to be configured. + * Param fircConfig : FIRC configuration. + * + *END**************************************************************************/ +static void CLOCK_CONFIG_FircSafeConfig(const scg_firc_config_t *fircConfig) +{ + scg_sys_clk_config_t curConfig; + const scg_sirc_config_t scgSircConfig = {.enableMode = kSCG_SircEnable, + .div1 = kSCG_AsyncClkDisable, + .div3 = kSCG_AsyncClkDivBy2, + .range = kSCG_SircRangeHigh}; + scg_sys_clk_config_t sysClkSafeConfigSource = { + .divSlow = kSCG_SysClkDivBy4, /* Slow clock divider */ +#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) + .reserved1 = 0, + .reserved2 = 0, + .reserved3 = 0, +#endif + .divCore = kSCG_SysClkDivBy1, /* Core clock divider */ +#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) + .reserved4 = 0, +#endif + .src = kSCG_SysClkSrcSirc, /* System clock source */ +#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) + .reserved5 = 0, +#endif + }; + /* Init Sirc. */ + CLOCK_InitSirc(&scgSircConfig); + /* Change to use SIRC as system clock source to prepare to change FIRCCFG register. */ + CLOCK_SetRunModeSysClkConfig(&sysClkSafeConfigSource); + /* Wait for clock source switch finished. */ + do + { + CLOCK_GetCurSysClkConfig(&curConfig); + } while (curConfig.src != sysClkSafeConfigSource.src); + + /* Init Firc. */ + CLOCK_InitFirc(fircConfig); + /* Change back to use FIRC as system clock source in order to configure SIRC if needed. */ + sysClkSafeConfigSource.src = kSCG_SysClkSrcFirc; + CLOCK_SetRunModeSysClkConfig(&sysClkSafeConfigSource); + /* Wait for clock source switch finished. */ + do + { + CLOCK_GetCurSysClkConfig(&curConfig); + } while (curConfig.src != sysClkSafeConfigSource.src); +} + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ +void BOARD_InitBootClocks(void) +{ + BOARD_BootClockRUN(); +} + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockRUN +called_from_default_init: true +outputs: +- {id: Core_clock.outFreq, value: 48 MHz} +- {id: FIRCDIV1_CLK.outFreq, value: 48 MHz} +- {id: FIRCDIV3_CLK.outFreq, value: 48 MHz} +- {id: LPO_clock.outFreq, value: 1 kHz} +- {id: OSC32KCLK.outFreq, value: 32.768 kHz} +- {id: SIRCDIV3_CLK.outFreq, value: 4 MHz} +- {id: SIRC_CLK.outFreq, value: 8 MHz} +- {id: SOSCDIV3_CLK.outFreq, value: 32.768 kHz} +- {id: SOSCER_CLK.outFreq, value: 32.768 kHz} +- {id: SOSC_CLK.outFreq, value: 32.768 kHz} +- {id: Slow_clock.outFreq, value: 24 MHz} +- {id: System_clock.outFreq, value: 48 MHz} +settings: +- {id: SCG.FIRCDIV1.scale, value: '1', locked: true} +- {id: SCG.FIRCDIV3.scale, value: '1', locked: true} +- {id: SCG.SIRCDIV3.scale, value: '2', locked: true} +- {id: SCG.SOSCDIV3.scale, value: '1', locked: true} +- {id: SCG_SOSCCFG_OSC_MODE_CFG, value: ModeOscLowPower} +- {id: SCG_SOSCCSR_SOSCEN_CFG, value: Enabled} +- {id: SCG_SOSCCSR_SOSCERCLKEN_CFG, value: Enabled} +sources: +- {id: SCG.SOSC.outFreq, value: 32.768 kHz, enabled: true} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockRUN configuration + ******************************************************************************/ +const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockRUN = + { + .divSlow = kSCG_SysClkDivBy2, /* Slow Clock Divider: divided by 2 */ +#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) + .reserved1 = 0, + .reserved2 = 0, + .reserved3 = 0, +#endif + .divCore = kSCG_SysClkDivBy1, /* Core Clock Divider: divided by 1 */ +#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) + .reserved4 = 0, +#endif + .src = kSCG_SysClkSrcFirc, /* Fast IRC is selected as System Clock Source */ +#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) + .reserved5 = 0, +#endif + }; +const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockRUN = + { + .freq = 32768U, /* System Oscillator frequency: 32768Hz */ + .enableMode = kSCG_SysOscEnable | kSCG_SysOscEnableErClk,/* Enable System OSC clock, Enable OSCERCLK */ + .monitorMode = kSCG_SysOscMonitorDisable, /* Monitor disabled */ + .div1 = kSCG_AsyncClkDisable, /* System OSC Clock Divider 1: Clock output is disabled */ + .div3 = kSCG_AsyncClkDivBy1, /* System OSC Clock Divider 3: divided by 1 */ + .capLoad = SCG_SYS_OSC_CAP_0P, /* Oscillator capacity load: 0pF */ + .workMode = kSCG_SysOscModeOscLowPower, /* Oscillator low power */ + }; +const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockRUN = + { + .enableMode = kSCG_SircEnable | kSCG_SircEnableInLowPower,/* Enable SIRC clock, Enable SIRC in low power mode */ + .div1 = kSCG_AsyncClkDisable, /* Slow IRC Clock Divider 1: Clock output is disabled */ + .div3 = kSCG_AsyncClkDivBy2, /* Slow IRC Clock Divider 3: divided by 2 */ + .range = kSCG_SircRangeHigh, /* Slow IRC high range clock (8 MHz) */ + }; +const scg_firc_config_t g_scgFircConfig_BOARD_BootClockRUN = + { + .enableMode = kSCG_FircEnable, /* Enable FIRC clock */ + .div1 = kSCG_AsyncClkDivBy1, /* Fast IRC Clock Divider 1: divided by 1 */ + .div3 = kSCG_AsyncClkDivBy1, /* Fast IRC Clock Divider 3: divided by 1 */ + .range = kSCG_FircRange48M, /* Fast IRC is trimmed to 48MHz */ + .trimConfig = NULL, /* Fast IRC Trim disabled */ + }; +const scg_spll_config_t g_scgSysPllConfig_BOARD_BootClockRUN = + { + .enableMode = SCG_SPLL_DISABLE, /* System PLL disabled */ + .monitorMode = kSCG_SysPllMonitorDisable, /* Monitor disabled */ + .div1 = kSCG_AsyncClkDisable, /* System PLL Clock Divider 1: Clock output is disabled */ + .div3 = kSCG_AsyncClkDisable, /* System PLL Clock Divider 3: Clock output is disabled */ + .src = kSCG_SysPllSrcSysOsc, /* System PLL clock source is System OSC */ + .prediv = 0, /* Divided by 1 */ + .mult = 0, /* Multiply Factor is 16 */ + }; +/******************************************************************************* + * Code for BOARD_BootClockRUN configuration + ******************************************************************************/ +void BOARD_BootClockRUN(void) +{ + scg_sys_clk_config_t curConfig; + + /* Init SOSC according to board configuration. */ + CLOCK_InitSysOsc(&g_scgSysOscConfig_BOARD_BootClockRUN); + /* Set the XTAL0 frequency based on board settings. */ + CLOCK_SetXtal0Freq(g_scgSysOscConfig_BOARD_BootClockRUN.freq); + /* Init FIRC. */ + CLOCK_CONFIG_FircSafeConfig(&g_scgFircConfig_BOARD_BootClockRUN); + /* Init SIRC. */ + CLOCK_InitSirc(&g_scgSircConfig_BOARD_BootClockRUN); + /* Set SCG to FIRC mode. */ + CLOCK_SetRunModeSysClkConfig(&g_sysClkConfig_BOARD_BootClockRUN); + /* Wait for clock source switch finished. */ + do + { + CLOCK_GetCurSysClkConfig(&curConfig); + } while (curConfig.src != g_sysClkConfig_BOARD_BootClockRUN.src); + /* Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; +} + +/******************************************************************************* + ********************* Configuration BOARD_BootClockHSRUN ********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockHSRUN +outputs: +- {id: CLKOUT.outFreq, value: 8 MHz} +- {id: Core_clock.outFreq, value: 96 MHz, locked: true, accuracy: '0.001'} +- {id: FIRCDIV1_CLK.outFreq, value: 48 MHz} +- {id: FIRCDIV3_CLK.outFreq, value: 48 MHz} +- {id: LPO_clock.outFreq, value: 1 kHz} +- {id: OSC32KCLK.outFreq, value: 32.768 kHz} +- {id: PLLDIV1_CLK.outFreq, value: 96 MHz} +- {id: PLLDIV3_CLK.outFreq, value: 96 MHz} +- {id: SIRCDIV1_CLK.outFreq, value: 8 MHz} +- {id: SIRCDIV3_CLK.outFreq, value: 8 MHz} +- {id: SIRC_CLK.outFreq, value: 8 MHz} +- {id: SOSCDIV1_CLK.outFreq, value: 32.768 kHz} +- {id: SOSCDIV3_CLK.outFreq, value: 32.768 kHz} +- {id: SOSCER_CLK.outFreq, value: 32.768 kHz} +- {id: SOSC_CLK.outFreq, value: 32.768 kHz} +- {id: Slow_clock.outFreq, value: 24 MHz, locked: true, accuracy: '0.001'} +- {id: System_clock.outFreq, value: 96 MHz} +settings: +- {id: SCGMode, value: SPLL} +- {id: powerMode, value: HSRUN} +- {id: CLKOUTConfig, value: 'yes'} +- {id: SCG.DIVSLOW.scale, value: '4'} +- {id: SCG.FIRCDIV1.scale, value: '1', locked: true} +- {id: SCG.FIRCDIV3.scale, value: '1', locked: true} +- {id: SCG.PREDIV.scale, value: '4'} +- {id: SCG.SCSSEL.sel, value: SCG.SPLL_DIV2_CLK} +- {id: SCG.SIRCDIV1.scale, value: '1', locked: true} +- {id: SCG.SIRCDIV3.scale, value: '1', locked: true} +- {id: SCG.SOSCDIV1.scale, value: '1', locked: true} +- {id: SCG.SOSCDIV3.scale, value: '1', locked: true} +- {id: SCG.SPLLDIV1.scale, value: '1', locked: true} +- {id: SCG.SPLLDIV3.scale, value: '1', locked: true} +- {id: SCG.SPLLSRCSEL.sel, value: SCG.FIRC} +- {id: SCG_SOSCCFG_OSC_MODE_CFG, value: ModeOscLowPower} +- {id: SCG_SOSCCSR_SOSCEN_CFG, value: Enabled} +- {id: SCG_SOSCCSR_SOSCERCLKEN_CFG, value: Enabled} +- {id: SCG_SPLLCSR_SPLLEN_CFG, value: Enabled} +sources: +- {id: SCG.SOSC.outFreq, value: 32.768 kHz, enabled: true} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockHSRUN configuration + ******************************************************************************/ +const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockHSRUN = + { + .divSlow = kSCG_SysClkDivBy4, /* Slow Clock Divider: divided by 4 */ +#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) + .reserved1 = 0, + .reserved2 = 0, + .reserved3 = 0, +#endif + .divCore = kSCG_SysClkDivBy1, /* Core Clock Divider: divided by 1 */ +#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) + .reserved4 = 0, +#endif + .src = kSCG_SysClkSrcSysPll, /* System PLL is selected as System Clock Source */ +#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) + .reserved5 = 0, +#endif + }; +const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockHSRUN = + { + .freq = 32768U, /* System Oscillator frequency: 32768Hz */ + .enableMode = kSCG_SysOscEnable | kSCG_SysOscEnableErClk,/* Enable System OSC clock, Enable OSCERCLK */ + .monitorMode = kSCG_SysOscMonitorDisable, /* Monitor disabled */ + .div1 = kSCG_AsyncClkDivBy1, /* System OSC Clock Divider 1: divided by 1 */ + .div3 = kSCG_AsyncClkDivBy1, /* System OSC Clock Divider 3: divided by 1 */ + .capLoad = SCG_SYS_OSC_CAP_0P, /* Oscillator capacity load: 0pF */ + .workMode = kSCG_SysOscModeOscLowPower, /* Oscillator low power */ + }; +const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockHSRUN = + { + .enableMode = kSCG_SircEnable | kSCG_SircEnableInLowPower,/* Enable SIRC clock, Enable SIRC in low power mode */ + .div1 = kSCG_AsyncClkDivBy1, /* Slow IRC Clock Divider 1: divided by 1 */ + .div3 = kSCG_AsyncClkDivBy1, /* Slow IRC Clock Divider 3: divided by 1 */ + .range = kSCG_SircRangeHigh, /* Slow IRC high range clock (8 MHz) */ + }; +const scg_firc_config_t g_scgFircConfig_BOARD_BootClockHSRUN = + { + .enableMode = kSCG_FircEnable, /* Enable FIRC clock */ + .div1 = kSCG_AsyncClkDivBy1, /* Fast IRC Clock Divider 1: divided by 1 */ + .div3 = kSCG_AsyncClkDivBy1, /* Fast IRC Clock Divider 3: divided by 1 */ + .range = kSCG_FircRange48M, /* Fast IRC is trimmed to 48MHz */ + .trimConfig = NULL, /* Fast IRC Trim disabled */ + }; +const scg_spll_config_t g_scgSysPllConfig_BOARD_BootClockHSRUN = + { + .enableMode = kSCG_SysPllEnable, /* Enable SPLL clock */ + .monitorMode = kSCG_SysPllMonitorDisable, /* Monitor disabled */ + .div1 = kSCG_AsyncClkDivBy1, /* System PLL Clock Divider 1: divided by 1 */ + .div3 = kSCG_AsyncClkDivBy1, /* System PLL Clock Divider 3: divided by 1 */ + .src = kSCG_SysPllSrcFirc, /* System PLL clock source is Fast IRC */ + .prediv = 3, /* Divided by 4 */ + .mult = 0, /* Multiply Factor is 16 */ + }; +/******************************************************************************* + * Code for BOARD_BootClockHSRUN configuration + ******************************************************************************/ +void BOARD_BootClockHSRUN(void) +{ + scg_sys_clk_config_t curConfig; + + /* Init SOSC according to board configuration. */ + CLOCK_InitSysOsc(&g_scgSysOscConfig_BOARD_BootClockHSRUN); + /* Set the XTAL0 frequency based on board settings. */ + CLOCK_SetXtal0Freq(g_scgSysOscConfig_BOARD_BootClockHSRUN.freq); + /* Init FIRC. */ + CLOCK_CONFIG_FircSafeConfig(&g_scgFircConfig_BOARD_BootClockHSRUN); + /* Init SIRC. */ + CLOCK_InitSirc(&g_scgSircConfig_BOARD_BootClockHSRUN); + /* Init SysPll. */ + CLOCK_InitSysPll(&g_scgSysPllConfig_BOARD_BootClockHSRUN); + /* Set HSRUN power mode. */ + SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll); + SMC_SetPowerModeHsrun(SMC); + while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateHsrun) + { + } + + /* Set SCG to SPLL mode. */ + CLOCK_SetHsrunModeSysClkConfig(&g_sysClkConfig_BOARD_BootClockHSRUN); + /* Wait for clock source switch finished. */ + do + { + CLOCK_GetCurSysClkConfig(&curConfig); + } while (curConfig.src != g_sysClkConfig_BOARD_BootClockHSRUN.src); + /* Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKHSRUN_CORE_CLOCK; + /* Set SCG CLKOUT selection. */ + CLOCK_CONFIG_SetScgOutSel(SCG_CLKOUTCNFG_SIRC); +} + +/******************************************************************************* + ********************* Configuration BOARD_BootClockVLPR *********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockVLPR +outputs: +- {id: Core_clock.outFreq, value: 8 MHz, locked: true, accuracy: '0.001'} +- {id: LPO_clock.outFreq, value: 1 kHz} +- {id: SIRC_CLK.outFreq, value: 8 MHz} +- {id: Slow_clock.outFreq, value: 1 MHz, locked: true, accuracy: '0.001'} +- {id: System_clock.outFreq, value: 8 MHz} +settings: +- {id: SCGMode, value: SIRC} +- {id: powerMode, value: VLPR} +- {id: SCG.DIVSLOW.scale, value: '8'} +- {id: SCG.SCSSEL.sel, value: SCG.SIRC} +- {id: SCG_FIRCCSR_FIRCLPEN_CFG, value: Enabled} +sources: +- {id: SCG.SOSC.outFreq, value: 32.768 kHz, enabled: true} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockVLPR configuration + ******************************************************************************/ +const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockVLPR = + { + .divSlow = kSCG_SysClkDivBy8, /* Slow Clock Divider: divided by 8 */ +#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) + .reserved1 = 0, + .reserved2 = 0, + .reserved3 = 0, +#endif + .divCore = kSCG_SysClkDivBy1, /* Core Clock Divider: divided by 1 */ +#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) + .reserved4 = 0, +#endif + .src = kSCG_SysClkSrcSirc, /* Slow IRC is selected as System Clock Source */ +#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) + .reserved5 = 0, +#endif + }; +const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockVLPR = + { + .freq = 0U, /* System Oscillator frequency: 0Hz */ + .enableMode = SCG_SOSC_DISABLE, /* System OSC disabled */ + .monitorMode = kSCG_SysOscMonitorDisable, /* Monitor disabled */ + .div1 = kSCG_AsyncClkDisable, /* System OSC Clock Divider 1: Clock output is disabled */ + .div3 = kSCG_AsyncClkDisable, /* System OSC Clock Divider 3: Clock output is disabled */ + .capLoad = SCG_SYS_OSC_CAP_0P, /* Oscillator capacity load: 0pF */ + .workMode = kSCG_SysOscModeExt, /* Use external clock */ + }; +const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockVLPR = + { + .enableMode = kSCG_SircEnable | kSCG_SircEnableInLowPower,/* Enable SIRC clock, Enable SIRC in low power mode */ + .div1 = kSCG_AsyncClkDisable, /* Slow IRC Clock Divider 1: Clock output is disabled */ + .div3 = kSCG_AsyncClkDisable, /* Slow IRC Clock Divider 3: Clock output is disabled */ + .range = kSCG_SircRangeHigh, /* Slow IRC high range clock (8 MHz) */ + }; +const scg_firc_config_t g_scgFircConfig_BOARD_BootClockVLPR = + { + .enableMode = kSCG_FircEnable | kSCG_FircEnableInLowPower,/* Enable FIRC clock, Enable FIRC in low power mode */ + .div1 = kSCG_AsyncClkDisable, /* Fast IRC Clock Divider 1: Clock output is disabled */ + .div3 = kSCG_AsyncClkDisable, /* Fast IRC Clock Divider 3: Clock output is disabled */ + .range = kSCG_FircRange48M, /* Fast IRC is trimmed to 48MHz */ + .trimConfig = NULL, /* Fast IRC Trim disabled */ + }; +const scg_spll_config_t g_scgSysPllConfig_BOARD_BootClockVLPR = + { + .enableMode = SCG_SPLL_DISABLE, /* System PLL disabled */ + .monitorMode = kSCG_SysPllMonitorDisable, /* Monitor disabled */ + .div1 = kSCG_AsyncClkDisable, /* System PLL Clock Divider 1: Clock output is disabled */ + .div3 = kSCG_AsyncClkDisable, /* System PLL Clock Divider 3: Clock output is disabled */ + .src = kSCG_SysPllSrcSysOsc, /* System PLL clock source is System OSC */ + .prediv = 0, /* Divided by 1 */ + .mult = 0, /* Multiply Factor is 16 */ + }; +/******************************************************************************* + * Code for BOARD_BootClockVLPR configuration + ******************************************************************************/ +void BOARD_BootClockVLPR(void) +{ + /* Init FIRC. */ + CLOCK_CONFIG_FircSafeConfig(&g_scgFircConfig_BOARD_BootClockVLPR); + /* Init SIRC. */ + CLOCK_InitSirc(&g_scgSircConfig_BOARD_BootClockVLPR); + /* Allow SMC all power modes. */ + SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll); + /* Set VLPR power mode. */ + SMC_SetPowerModeVlpr(SMC); + while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateVlpr) + { + } + /* Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKVLPR_CORE_CLOCK; +} diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/clock_config.h b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/clock_config.h new file mode 100644 index 000000000..c01d5e03c --- /dev/null +++ b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/clock_config.h @@ -0,0 +1,164 @@ +/* + * Copyright 2019 ,2021 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _CLOCK_CONFIG_H_ +#define _CLOCK_CONFIG_H_ + +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define BOARD_XTAL0_CLK_HZ 32768U /*!< Board xtal0 frequency in Hz */ + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes default configuration of clocks. + * + */ +void BOARD_InitBootClocks(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockRUN configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */ + +/*! @brief SCG set for BOARD_BootClockRUN configuration. + */ +extern const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockRUN; +/*! @brief System OSC set for BOARD_BootClockRUN configuration. + */ +extern const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockRUN; +/*! @brief SIRC set for BOARD_BootClockRUN configuration. + */ +extern const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockRUN; +/*! @brief FIRC set for BOARD_BootClockRUN configuration. + */ +extern const scg_firc_config_t g_scgFircConfigBOARD_BootClockRUN; +extern const scg_spll_config_t g_scgSysPllConfigBOARD_BootClockRUN; +/*! @brief Low Power FLL set for BOARD_BootClockRUN configuration. + */ + +/******************************************************************************* + * API for BOARD_BootClockRUN configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockRUN(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ********************* Configuration BOARD_BootClockHSRUN ********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockHSRUN configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKHSRUN_CORE_CLOCK 96000000U /*!< Core clock frequency: 96000000Hz */ + +/*! @brief SCG set for BOARD_BootClockHSRUN configuration. + */ +extern const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockHSRUN; +/*! @brief System OSC set for BOARD_BootClockHSRUN configuration. + */ +extern const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockHSRUN; +/*! @brief SIRC set for BOARD_BootClockHSRUN configuration. + */ +extern const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockHSRUN; +/*! @brief FIRC set for BOARD_BootClockHSRUN configuration. + */ +extern const scg_firc_config_t g_scgFircConfigBOARD_BootClockHSRUN; +extern const scg_spll_config_t g_scgSysPllConfigBOARD_BootClockHSRUN; +/*! @brief Low Power FLL set for BOARD_BootClockHSRUN configuration. + */ + +/******************************************************************************* + * API for BOARD_BootClockHSRUN configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockHSRUN(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ********************* Configuration BOARD_BootClockVLPR *********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockVLPR configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKVLPR_CORE_CLOCK 8000000U /*!< Core clock frequency: 8000000Hz */ + +/*! @brief SCG set for BOARD_BootClockVLPR configuration. + */ +extern const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockVLPR; +/*! @brief System OSC set for BOARD_BootClockVLPR configuration. + */ +extern const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockVLPR; +/*! @brief SIRC set for BOARD_BootClockVLPR configuration. + */ +extern const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockVLPR; +/*! @brief FIRC set for BOARD_BootClockVLPR configuration. + */ +extern const scg_firc_config_t g_scgFircConfigBOARD_BootClockVLPR; +extern const scg_spll_config_t g_scgSysPllConfigBOARD_BootClockVLPR; +/*! @brief Low Power FLL set for BOARD_BootClockVLPR configuration. + */ + +/******************************************************************************* + * API for BOARD_BootClockVLPR configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockVLPR(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +#endif /* _CLOCK_CONFIG_H_ */ diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.mk b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.mk index 82456b721..9cf36c500 100644 --- a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.mk +++ b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.mk @@ -8,9 +8,6 @@ CFLAGS += -Wno-error=unused-parameter -Wno-error=redundant-decls # All source paths should be relative to the top level. LD_FILE = $(MCU_DIR)/gcc/K32L2B31xxxxA_flash.ld -SRC_C += \ - $(MCU_DIR)/project_template/clock_config.c \ - # For flash-jlink target JLINK_DEVICE = K32L2B31xxxxA diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.c b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.c new file mode 100644 index 000000000..e74000827 --- /dev/null +++ b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.c @@ -0,0 +1,220 @@ +/* + * Copyright 2019 ,2021 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ +/* + * How to setup clock using clock driver functions: + * + * 1. CLOCK_SetSimSafeDivs, to make sure core clock, bus clock, flexbus clock + * and flash clock are in allowed range during clock mode switch. + * + * 2. Call CLOCK_Osc0Init to setup OSC clock, if it is used in target mode. + * + * 3. Call CLOCK_SetMcgliteConfig to set MCG_Lite configuration. + * + * 4. Call CLOCK_SetSimConfig to set the clock configuration in SIM. + */ + +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Clocks v7.0 +processor: K32L2B31xxxxA +package_id: K32L2B31VLH0A +mcu_data: ksdk2_0 +processor_version: 9.0.0 +board: FRDM-K32L2B + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +#include "fsl_smc.h" +#include "clock_config.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define OSC_CAP0P 0U /*!< Oscillator 0pF capacitor load */ +#define OSC_ER_CLK_DISABLE 0U /*!< Disable external reference clock */ +#define SIM_OSC32KSEL_OSC32KCLK_CLK 0U /*!< OSC32KSEL select: OSC32KCLK clock */ + +/******************************************************************************* + * Variables + ******************************************************************************/ +/* System clock frequency. */ +extern uint32_t SystemCoreClock; + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ +void BOARD_InitBootClocks(void) +{ + BOARD_BootClockRUN(); +} + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockRUN +called_from_default_init: true +outputs: +- {id: Bus_clock.outFreq, value: 24 MHz} +- {id: Core_clock.outFreq, value: 48 MHz} +- {id: Flash_clock.outFreq, value: 24 MHz} +- {id: LPO_clock.outFreq, value: 1 kHz} +- {id: MCGIRCLK.outFreq, value: 8 MHz} +- {id: MCGPCLK.outFreq, value: 48 MHz} +- {id: System_clock.outFreq, value: 48 MHz} +settings: +- {id: MCGMode, value: HIRC} +- {id: MCG.CLKS.sel, value: MCG.HIRC} +- {id: MCG_C2_OSC_MODE_CFG, value: ModeOscLowPower} +- {id: MCG_C2_RANGE0_CFG, value: Very_high} +- {id: MCG_MC_HIRCEN_CFG, value: Enabled} +- {id: OSC0_CR_ERCLKEN_CFG, value: Enabled} +- {id: OSC_CR_ERCLKEN_CFG, value: Enabled} +- {id: SIM.CLKOUTSEL.sel, value: MCG.MCGPCLK} +- {id: SIM.COPCLKSEL.sel, value: OSC.OSCERCLK} +- {id: SIM.FLEXIOSRCSEL.sel, value: MCG.MCGPCLK} +- {id: SIM.LPUART0SRCSEL.sel, value: MCG.MCGPCLK} +- {id: SIM.LPUART1SRCSEL.sel, value: MCG.MCGPCLK} +- {id: SIM.RTCCLKOUTSEL.sel, value: OSC.OSCERCLK} +- {id: SIM.TPMSRCSEL.sel, value: MCG.MCGPCLK} +- {id: SIM.USBSRCSEL.sel, value: MCG.MCGPCLK} +sources: +- {id: MCG.HIRC.outFreq, value: 48 MHz} +- {id: OSC.OSC.outFreq, value: 32 MHz} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * 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_OSC32KCLK_CLK, /* OSC32KSEL select: OSC32KCLK clock */ + .clkdiv1 = 0x10000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV4: /2 */ + }; +const osc_config_t oscConfig_BOARD_BootClockRUN = + { + .freq = 0U, /* Oscillator frequency: 0Hz */ + .capLoad = (OSC_CAP0P), /* Oscillator capacity load: 0pF */ + .workMode = kOSC_ModeOscLowPower, /* Oscillator low power */ + .oscerConfig = + { + .enableMode = kOSC_ErClkEnable, /* Enable external reference clock, disable external reference clock in STOP mode */ + } + }; + +/******************************************************************************* + * 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; +} + +/******************************************************************************* + ********************* Configuration BOARD_BootClockVLPR *********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockVLPR +outputs: +- {id: Bus_clock.outFreq, value: 1 MHz} +- {id: Core_clock.outFreq, value: 2 MHz} +- {id: Flash_clock.outFreq, value: 1 MHz} +- {id: LPO_clock.outFreq, value: 1 kHz} +- {id: MCGIRCLK.outFreq, value: 2 MHz} +- {id: System_clock.outFreq, value: 2 MHz} +settings: +- {id: MCGMode, value: LIRC2M} +- {id: powerMode, value: VLPR} +- {id: MCG_C2_OSC_MODE_CFG, value: ModeOscLowPower} +- {id: RTCCLKOUTConfig, value: 'yes'} +- {id: SIM.OUTDIV4.scale, value: '2', locked: true} +- {id: SIM.RTCCLKOUTSEL.sel, value: OSC.OSCERCLK} +sources: +- {id: MCG.LIRC.outFreq, value: 2 MHz} +- {id: OSC.OSC.outFreq, value: 32.768 kHz} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockVLPR configuration + ******************************************************************************/ +const mcglite_config_t mcgliteConfig_BOARD_BootClockVLPR = + { + .outSrc = kMCGLITE_ClkSrcLirc, /* MCGOUTCLK source is LIRC */ + .irclkEnableMode = kMCGLITE_IrclkEnable, /* MCGIRCLK enabled, MCGIRCLK disabled in STOP mode */ + .ircs = kMCGLITE_Lirc2M, /* Slow internal reference (LIRC) 2 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 = false, /* HIRC source is not enabled */ + }; +const sim_clock_config_t simConfig_BOARD_BootClockVLPR = + { + .er32kSrc = SIM_OSC32KSEL_OSC32KCLK_CLK, /* OSC32KSEL select: OSC32KCLK clock */ + .clkdiv1 = 0x10000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV4: /2 */ + }; +const osc_config_t oscConfig_BOARD_BootClockVLPR = + { + .freq = 0U, /* Oscillator frequency: 0Hz */ + .capLoad = (OSC_CAP0P), /* Oscillator capacity load: 0pF */ + .workMode = kOSC_ModeOscLowPower, /* Oscillator low power */ + .oscerConfig = + { + .enableMode = OSC_ER_CLK_DISABLE, /* Disable external reference clock */ + } + }; + +/******************************************************************************* + * Code for BOARD_BootClockVLPR configuration + ******************************************************************************/ +void BOARD_BootClockVLPR(void) +{ + /* Set the system clock dividers in SIM to safe value. */ + CLOCK_SetSimSafeDivs(); + /* Set MCG to LIRC2M mode. */ + CLOCK_SetMcgliteConfig(&mcgliteConfig_BOARD_BootClockVLPR); + /* Set the clock configuration in SIM module. */ + CLOCK_SetSimConfig(&simConfig_BOARD_BootClockVLPR); + /* Set VLPR power mode. */ + SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll); +#if (defined(FSL_FEATURE_SMC_HAS_LPWUI) && FSL_FEATURE_SMC_HAS_LPWUI) + SMC_SetPowerModeVlpr(SMC, false); +#else + SMC_SetPowerModeVlpr(SMC); +#endif + while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateVlpr) + { + } + /* Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKVLPR_CORE_CLOCK; +} diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.h b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.h new file mode 100644 index 000000000..37328e7d8 --- /dev/null +++ b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.h @@ -0,0 +1,110 @@ +/* + * Copyright 2019 ,2021 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _CLOCK_CONFIG_H_ +#define _CLOCK_CONFIG_H_ + +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes default configuration of clocks. + * + */ +void BOARD_InitBootClocks(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockRUN configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */ + +/*! @brief MCG lite set for BOARD_BootClockRUN configuration. + */ +extern const mcglite_config_t mcgliteConfig_BOARD_BootClockRUN; +/*! @brief SIM module set for BOARD_BootClockRUN configuration. + */ +extern const sim_clock_config_t simConfig_BOARD_BootClockRUN; +/*! @brief OSC set for BOARD_BootClockRUN configuration. + */ +extern const osc_config_t oscConfig_BOARD_BootClockRUN; + +/******************************************************************************* + * API for BOARD_BootClockRUN configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockRUN(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ********************* Configuration BOARD_BootClockVLPR *********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockVLPR configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKVLPR_CORE_CLOCK 2000000U /*!< Core clock frequency: 2000000Hz */ + +/*! @brief MCG lite set for BOARD_BootClockVLPR configuration. + */ +extern const mcglite_config_t mcgliteConfig_BOARD_BootClockVLPR; +/*! @brief SIM module set for BOARD_BootClockVLPR configuration. + */ +extern const sim_clock_config_t simConfig_BOARD_BootClockVLPR; +/*! @brief OSC set for BOARD_BootClockVLPR configuration. + */ +extern const osc_config_t oscConfig_BOARD_BootClockVLPR; + +/******************************************************************************* + * API for BOARD_BootClockVLPR configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockVLPR(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +#endif /* _CLOCK_CONFIG_H_ */ From 1315bc196c9b8944bb738994df3dc22e54c8f020 Mon Sep 17 00:00:00 2001 From: Xudong Zheng <7pkvm5aw@slicealias.com> Date: Mon, 19 Feb 2024 16:52:09 -0500 Subject: [PATCH 116/454] Fix nRF5340 DK USB host shield build - Fix incorrect UART pins - Enable MAX3421 host shield - Use GPIOTE1_IRQn instead of GPIOTE_IRQn --- hw/bsp/nrf/boards/pca10095/board.cmake | 3 +++ hw/bsp/nrf/boards/pca10095/board.h | 4 ++-- hw/bsp/nrf/boards/pca10095/board.mk | 3 +++ hw/bsp/nrf/family.c | 1 + 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/hw/bsp/nrf/boards/pca10095/board.cmake b/hw/bsp/nrf/boards/pca10095/board.cmake index ca5399a3a..0fbc1d31f 100644 --- a/hw/bsp/nrf/boards/pca10095/board.cmake +++ b/hw/bsp/nrf/boards/pca10095/board.cmake @@ -1,6 +1,9 @@ set(MCU_VARIANT nrf5340_application) set(LD_FILE_GNU ${NRFX_DIR}/mdk/nrf5340_xxaa_application.ld) +# enable max3421 host driver for this board +set(MAX3421_HOST 1) + function(update_board TARGET) target_sources(${TARGET} PRIVATE ${NRFX_DIR}/drivers/src/nrfx_usbreg.c diff --git a/hw/bsp/nrf/boards/pca10095/board.h b/hw/bsp/nrf/boards/pca10095/board.h index ad3379bf6..7437dad48 100644 --- a/hw/bsp/nrf/boards/pca10095/board.h +++ b/hw/bsp/nrf/boards/pca10095/board.h @@ -42,8 +42,8 @@ #define BUTTON_STATE_ACTIVE 0 // UART -#define UART_RX_PIN 32 -#define UART_TX_PIN 33 +#define UART_RX_PIN 22 +#define UART_TX_PIN 20 // SPI for USB host shield #define MAX3421_SCK_PIN _PINNUM(1, 15) diff --git a/hw/bsp/nrf/boards/pca10095/board.mk b/hw/bsp/nrf/boards/pca10095/board.mk index 9c4edbafc..20580d619 100644 --- a/hw/bsp/nrf/boards/pca10095/board.mk +++ b/hw/bsp/nrf/boards/pca10095/board.mk @@ -2,6 +2,9 @@ CPU_CORE = cortex-m33 MCU_VARIANT = nrf5340_application CFLAGS += -DNRF5340_XXAA -DNRF5340_XXAA_APPLICATION +# enable max3421 host driver for this board +MAX3421_HOST = 1 + LD_FILE = hw/mcu/nordic/nrfx/mdk/nrf5340_xxaa_application.ld SRC_C += hw/mcu/nordic/nrfx/drivers/src/nrfx_usbreg.c diff --git a/hw/bsp/nrf/family.c b/hw/bsp/nrf/family.c index 7a970f52e..55119ef02 100644 --- a/hw/bsp/nrf/family.c +++ b/hw/bsp/nrf/family.c @@ -76,6 +76,7 @@ enum { #define LFCLK_SRC_RC CLOCK_LFCLKSRC_SRC_LFRC #define VBUSDETECT_Msk USBREG_USBREGSTATUS_VBUSDETECT_Msk #define OUTPUTRDY_Msk USBREG_USBREGSTATUS_OUTPUTRDY_Msk + #define GPIOTE_IRQn GPIOTE1_IRQn #else #define LFCLK_SRC_RC CLOCK_LFCLKSRC_SRC_RC #define VBUSDETECT_Msk POWER_USBREGSTATUS_VBUSDETECT_Msk From 3f2df94457e917dda2fed05c7ee17deefe55199e Mon Sep 17 00:00:00 2001 From: Bob Abeles Date: Tue, 20 Feb 2024 08:16:39 -0800 Subject: [PATCH 117/454] video_device: fix uninitialized warning --- src/class/video/video_device.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index 1affd615e..c33dfa0b0 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -559,6 +559,7 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * uint_fast8_t num_intervals = frm->uncompressed.bFrameIntervalType; if (num_intervals) { interval = 0; + interval_ms = 0; } else { interval = frm->uncompressed.dwFrameInterval[2]; interval_ms = interval / 10000; From 5c14bd13da211ff2679115b0dba96ac80c1a516c Mon Sep 17 00:00:00 2001 From: Jerry Palacios Date: Tue, 20 Feb 2024 18:02:42 -0600 Subject: [PATCH 118/454] MCX A and MCX N merged to MCX family --- README.rst | 4 +- .../FreeRTOSConfig/FreeRTOSConfig.h | 0 .../boards/frdmmcxa153/board.cmake | 5 + .../{mcxa => mcx}/boards/frdmmcxa153/board.h | 0 .../{mcxa => mcx}/boards/frdmmcxa153/board.mk | 3 +- .../boards/frdmmcxa153/clock_config.c | 0 .../boards/frdmmcxa153/clock_config.h | 0 .../boards/frdmmcxa153/pin_mux.c | 0 .../boards/frdmmcxa153/pin_mux.h | 0 .../boards/frdmmcxn947/board.cmake | 3 + .../{mcxn => mcx}/boards/frdmmcxn947/board.h | 0 .../{mcxn => mcx}/boards/frdmmcxn947/board.mk | 5 +- .../boards/frdmmcxn947/clock_config.c | 0 .../boards/frdmmcxn947/clock_config.h | 0 .../boards/frdmmcxn947/pin_mux.c | 0 .../boards/frdmmcxn947/pin_mux.h | 0 .../boards/mcxn947brk/board.cmake | 3 + .../{mcxn => mcx}/boards/mcxn947brk/board.h | 0 .../{mcxn => mcx}/boards/mcxn947brk/board.mk | 5 +- .../boards/mcxn947brk/clock_config.c | 0 .../boards/mcxn947brk/clock_config.h | 0 .../{mcxn => mcx}/boards/mcxn947brk/pin_mux.c | 0 .../{mcxn => mcx}/boards/mcxn947brk/pin_mux.h | 0 hw/bsp/{mcxa => mcx}/debug.jlinkscript | 0 hw/bsp/{mcxn => mcx}/family.c | 26 ++- hw/bsp/{mcxn => mcx}/family.cmake | 24 ++- hw/bsp/{mcxn => mcx}/family.mk | 22 ++- hw/bsp/mcxa/family.c | 161 ------------------ hw/bsp/mcxa/family.cmake | 110 ------------ hw/bsp/mcxa/family.mk | 42 ----- hw/bsp/mcxn/FreeRTOSConfig/FreeRTOSConfig.h | 149 ---------------- hw/bsp/mcxn/debug.jlinkscript | 5 - src/common/tusb_mcu.h | 4 +- src/portable/chipidea/ci_fs/ci_fs_mcx.h | 17 +- src/portable/chipidea/ci_fs/ci_fs_mcxa.h | 47 ----- src/portable/chipidea/ci_fs/dcd_ci_fs.c | 2 - src/tusb_option.h | 2 +- 37 files changed, 99 insertions(+), 540 deletions(-) rename hw/bsp/{mcxa => mcx}/FreeRTOSConfig/FreeRTOSConfig.h (100%) rename hw/bsp/{mcxa => mcx}/boards/frdmmcxa153/board.cmake (76%) rename hw/bsp/{mcxa => mcx}/boards/frdmmcxa153/board.h (100%) rename hw/bsp/{mcxa => mcx}/boards/frdmmcxa153/board.mk (71%) rename hw/bsp/{mcxa => mcx}/boards/frdmmcxa153/clock_config.c (100%) rename hw/bsp/{mcxa => mcx}/boards/frdmmcxa153/clock_config.h (100%) rename hw/bsp/{mcxa => mcx}/boards/frdmmcxa153/pin_mux.c (100%) rename hw/bsp/{mcxa => mcx}/boards/frdmmcxa153/pin_mux.h (100%) rename hw/bsp/{mcxn => mcx}/boards/frdmmcxn947/board.cmake (83%) rename hw/bsp/{mcxn => mcx}/boards/frdmmcxn947/board.h (100%) rename hw/bsp/{mcxn => mcx}/boards/frdmmcxn947/board.mk (61%) rename hw/bsp/{mcxn => mcx}/boards/frdmmcxn947/clock_config.c (100%) rename hw/bsp/{mcxn => mcx}/boards/frdmmcxn947/clock_config.h (100%) rename hw/bsp/{mcxn => mcx}/boards/frdmmcxn947/pin_mux.c (100%) rename hw/bsp/{mcxn => mcx}/boards/frdmmcxn947/pin_mux.h (100%) rename hw/bsp/{mcxn => mcx}/boards/mcxn947brk/board.cmake (83%) rename hw/bsp/{mcxn => mcx}/boards/mcxn947brk/board.h (100%) rename hw/bsp/{mcxn => mcx}/boards/mcxn947brk/board.mk (61%) rename hw/bsp/{mcxn => mcx}/boards/mcxn947brk/clock_config.c (100%) rename hw/bsp/{mcxn => mcx}/boards/mcxn947brk/clock_config.h (100%) rename hw/bsp/{mcxn => mcx}/boards/mcxn947brk/pin_mux.c (100%) rename hw/bsp/{mcxn => mcx}/boards/mcxn947brk/pin_mux.h (100%) rename hw/bsp/{mcxa => mcx}/debug.jlinkscript (100%) rename hw/bsp/{mcxn => mcx}/family.c (93%) rename hw/bsp/{mcxn => mcx}/family.cmake (85%) rename hw/bsp/{mcxn => mcx}/family.mk (83%) delete mode 100644 hw/bsp/mcxa/family.c delete mode 100644 hw/bsp/mcxa/family.cmake delete mode 100644 hw/bsp/mcxa/family.mk delete mode 100644 hw/bsp/mcxn/FreeRTOSConfig/FreeRTOSConfig.h delete mode 100644 hw/bsp/mcxn/debug.jlinkscript delete mode 100644 src/portable/chipidea/ci_fs/ci_fs_mcxa.h diff --git a/README.rst b/README.rst index c48007c23..8c3145d33 100644 --- a/README.rst +++ b/README.rst @@ -139,9 +139,7 @@ Following CPUs are supported, check out `Supported Devices`_ for comprehensive l | +---------+--------------------------------------------------+ | | LPC | 11u, 13, 15, 17, 18, 40, 43, 51u, 54, 55 | | +---------+--------------------------------------------------+ -| | MCXA | A153 | -| +---------+--------------------------------------------------+ -| | MCXN | N9 | +| | MCX | A15, N9 | +--------------+---------+--------------------------------------------------+ | Raspberry Pi | RP2040 | +--------------+-----+------------------------------------------------------+ diff --git a/hw/bsp/mcxa/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/mcx/FreeRTOSConfig/FreeRTOSConfig.h similarity index 100% rename from hw/bsp/mcxa/FreeRTOSConfig/FreeRTOSConfig.h rename to hw/bsp/mcx/FreeRTOSConfig/FreeRTOSConfig.h diff --git a/hw/bsp/mcxa/boards/frdmmcxa153/board.cmake b/hw/bsp/mcx/boards/frdmmcxa153/board.cmake similarity index 76% rename from hw/bsp/mcxa/boards/frdmmcxa153/board.cmake rename to hw/bsp/mcx/boards/frdmmcxa153/board.cmake index 7f3c6c665..acde3f46f 100644 --- a/hw/bsp/mcxa/boards/frdmmcxa153/board.cmake +++ b/hw/bsp/mcx/boards/frdmmcxa153/board.cmake @@ -1,10 +1,15 @@ set(MCU_VARIANT MCXA153) set(MCU_CORE MCXA153) +set(FAMILY_MCUS MCXA15 CACHE INTERNAL "") +set(CMAKE_SYSTEM_PROCESSOR cortex-m33-nodsp-nofp CACHE INTERNAL "System Processor") + set(JLINK_DEVICE MCXA153_M33) set(PYOCD_TARGET MCXA153) set(NXPLINK_DEVICE MCXA153:MCXA153) +set(PORT 0) + function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC CPU_MCXA153VLH diff --git a/hw/bsp/mcxa/boards/frdmmcxa153/board.h b/hw/bsp/mcx/boards/frdmmcxa153/board.h similarity index 100% rename from hw/bsp/mcxa/boards/frdmmcxa153/board.h rename to hw/bsp/mcx/boards/frdmmcxa153/board.h diff --git a/hw/bsp/mcxa/boards/frdmmcxa153/board.mk b/hw/bsp/mcx/boards/frdmmcxa153/board.mk similarity index 71% rename from hw/bsp/mcxa/boards/frdmmcxa153/board.mk rename to hw/bsp/mcx/boards/frdmmcxa153/board.mk index 18f7e3cb5..a70a7dcef 100644 --- a/hw/bsp/mcxa/boards/frdmmcxa153/board.mk +++ b/hw/bsp/mcx/boards/frdmmcxa153/board.mk @@ -2,10 +2,11 @@ MCU_VARIANT = MCXA153 MCU_CORE = MCXA153 PORT = 0 +CPU_CORE ?= cortex-m33-nodsp-nofp CFLAGS += \ -DCPU_MCXA153VLH \ + -DCFG_TUSB_MCU=OPT_MCU_MCXA15 \ - JLINK_DEVICE = MCXA153 PYOCD_TARGET = MCXA153 diff --git a/hw/bsp/mcxa/boards/frdmmcxa153/clock_config.c b/hw/bsp/mcx/boards/frdmmcxa153/clock_config.c similarity index 100% rename from hw/bsp/mcxa/boards/frdmmcxa153/clock_config.c rename to hw/bsp/mcx/boards/frdmmcxa153/clock_config.c diff --git a/hw/bsp/mcxa/boards/frdmmcxa153/clock_config.h b/hw/bsp/mcx/boards/frdmmcxa153/clock_config.h similarity index 100% rename from hw/bsp/mcxa/boards/frdmmcxa153/clock_config.h rename to hw/bsp/mcx/boards/frdmmcxa153/clock_config.h diff --git a/hw/bsp/mcxa/boards/frdmmcxa153/pin_mux.c b/hw/bsp/mcx/boards/frdmmcxa153/pin_mux.c similarity index 100% rename from hw/bsp/mcxa/boards/frdmmcxa153/pin_mux.c rename to hw/bsp/mcx/boards/frdmmcxa153/pin_mux.c diff --git a/hw/bsp/mcxa/boards/frdmmcxa153/pin_mux.h b/hw/bsp/mcx/boards/frdmmcxa153/pin_mux.h similarity index 100% rename from hw/bsp/mcxa/boards/frdmmcxa153/pin_mux.h rename to hw/bsp/mcx/boards/frdmmcxa153/pin_mux.h diff --git a/hw/bsp/mcxn/boards/frdmmcxn947/board.cmake b/hw/bsp/mcx/boards/frdmmcxn947/board.cmake similarity index 83% rename from hw/bsp/mcxn/boards/frdmmcxn947/board.cmake rename to hw/bsp/mcx/boards/frdmmcxn947/board.cmake index 8c3280743..a08d248f5 100644 --- a/hw/bsp/mcxn/boards/frdmmcxn947/board.cmake +++ b/hw/bsp/mcx/boards/frdmmcxn947/board.cmake @@ -1,6 +1,9 @@ set(MCU_VARIANT MCXN947) set(MCU_CORE MCXN947_cm33_core0) +set(CMAKE_SYSTEM_PROCESSOR cortex-m33 CACHE INTERNAL "System Processor") +set(FAMILY_MCUS MCXN9 CACHE INTERNAL "") + set(JLINK_DEVICE MCXN947_M33_0) set(PYOCD_TARGET MCXN947) set(NXPLINK_DEVICE MCXN947:MCXN947) diff --git a/hw/bsp/mcxn/boards/frdmmcxn947/board.h b/hw/bsp/mcx/boards/frdmmcxn947/board.h similarity index 100% rename from hw/bsp/mcxn/boards/frdmmcxn947/board.h rename to hw/bsp/mcx/boards/frdmmcxn947/board.h diff --git a/hw/bsp/mcxn/boards/frdmmcxn947/board.mk b/hw/bsp/mcx/boards/frdmmcxn947/board.mk similarity index 61% rename from hw/bsp/mcxn/boards/frdmmcxn947/board.mk rename to hw/bsp/mcx/boards/frdmmcxn947/board.mk index aaad5e73e..d90780996 100644 --- a/hw/bsp/mcxn/boards/frdmmcxn947/board.mk +++ b/hw/bsp/mcx/boards/frdmmcxn947/board.mk @@ -2,7 +2,10 @@ MCU_VARIANT = MCXN947 MCU_CORE = MCXN947_cm33_core0 PORT ?= 1 -CFLAGS += -DCPU_MCXN947VDF_cm33_core0 +CPU_CORE ?= cortex-m33 +CFLAGS += \ + -DCPU_MCXN947VDF_cm33_core0 \ + -DCFG_TUSB_MCU=OPT_MCU_MCXN9 \ JLINK_DEVICE = MCXN947_M33_0 PYOCD_TARGET = MCXN947 diff --git a/hw/bsp/mcxn/boards/frdmmcxn947/clock_config.c b/hw/bsp/mcx/boards/frdmmcxn947/clock_config.c similarity index 100% rename from hw/bsp/mcxn/boards/frdmmcxn947/clock_config.c rename to hw/bsp/mcx/boards/frdmmcxn947/clock_config.c diff --git a/hw/bsp/mcxn/boards/frdmmcxn947/clock_config.h b/hw/bsp/mcx/boards/frdmmcxn947/clock_config.h similarity index 100% rename from hw/bsp/mcxn/boards/frdmmcxn947/clock_config.h rename to hw/bsp/mcx/boards/frdmmcxn947/clock_config.h diff --git a/hw/bsp/mcxn/boards/frdmmcxn947/pin_mux.c b/hw/bsp/mcx/boards/frdmmcxn947/pin_mux.c similarity index 100% rename from hw/bsp/mcxn/boards/frdmmcxn947/pin_mux.c rename to hw/bsp/mcx/boards/frdmmcxn947/pin_mux.c diff --git a/hw/bsp/mcxn/boards/frdmmcxn947/pin_mux.h b/hw/bsp/mcx/boards/frdmmcxn947/pin_mux.h similarity index 100% rename from hw/bsp/mcxn/boards/frdmmcxn947/pin_mux.h rename to hw/bsp/mcx/boards/frdmmcxn947/pin_mux.h diff --git a/hw/bsp/mcxn/boards/mcxn947brk/board.cmake b/hw/bsp/mcx/boards/mcxn947brk/board.cmake similarity index 83% rename from hw/bsp/mcxn/boards/mcxn947brk/board.cmake rename to hw/bsp/mcx/boards/mcxn947brk/board.cmake index 8c3280743..a08d248f5 100644 --- a/hw/bsp/mcxn/boards/mcxn947brk/board.cmake +++ b/hw/bsp/mcx/boards/mcxn947brk/board.cmake @@ -1,6 +1,9 @@ set(MCU_VARIANT MCXN947) set(MCU_CORE MCXN947_cm33_core0) +set(CMAKE_SYSTEM_PROCESSOR cortex-m33 CACHE INTERNAL "System Processor") +set(FAMILY_MCUS MCXN9 CACHE INTERNAL "") + set(JLINK_DEVICE MCXN947_M33_0) set(PYOCD_TARGET MCXN947) set(NXPLINK_DEVICE MCXN947:MCXN947) diff --git a/hw/bsp/mcxn/boards/mcxn947brk/board.h b/hw/bsp/mcx/boards/mcxn947brk/board.h similarity index 100% rename from hw/bsp/mcxn/boards/mcxn947brk/board.h rename to hw/bsp/mcx/boards/mcxn947brk/board.h diff --git a/hw/bsp/mcxn/boards/mcxn947brk/board.mk b/hw/bsp/mcx/boards/mcxn947brk/board.mk similarity index 61% rename from hw/bsp/mcxn/boards/mcxn947brk/board.mk rename to hw/bsp/mcx/boards/mcxn947brk/board.mk index aaad5e73e..d90780996 100644 --- a/hw/bsp/mcxn/boards/mcxn947brk/board.mk +++ b/hw/bsp/mcx/boards/mcxn947brk/board.mk @@ -2,7 +2,10 @@ MCU_VARIANT = MCXN947 MCU_CORE = MCXN947_cm33_core0 PORT ?= 1 -CFLAGS += -DCPU_MCXN947VDF_cm33_core0 +CPU_CORE ?= cortex-m33 +CFLAGS += \ + -DCPU_MCXN947VDF_cm33_core0 \ + -DCFG_TUSB_MCU=OPT_MCU_MCXN9 \ JLINK_DEVICE = MCXN947_M33_0 PYOCD_TARGET = MCXN947 diff --git a/hw/bsp/mcxn/boards/mcxn947brk/clock_config.c b/hw/bsp/mcx/boards/mcxn947brk/clock_config.c similarity index 100% rename from hw/bsp/mcxn/boards/mcxn947brk/clock_config.c rename to hw/bsp/mcx/boards/mcxn947brk/clock_config.c diff --git a/hw/bsp/mcxn/boards/mcxn947brk/clock_config.h b/hw/bsp/mcx/boards/mcxn947brk/clock_config.h similarity index 100% rename from hw/bsp/mcxn/boards/mcxn947brk/clock_config.h rename to hw/bsp/mcx/boards/mcxn947brk/clock_config.h diff --git a/hw/bsp/mcxn/boards/mcxn947brk/pin_mux.c b/hw/bsp/mcx/boards/mcxn947brk/pin_mux.c similarity index 100% rename from hw/bsp/mcxn/boards/mcxn947brk/pin_mux.c rename to hw/bsp/mcx/boards/mcxn947brk/pin_mux.c diff --git a/hw/bsp/mcxn/boards/mcxn947brk/pin_mux.h b/hw/bsp/mcx/boards/mcxn947brk/pin_mux.h similarity index 100% rename from hw/bsp/mcxn/boards/mcxn947brk/pin_mux.h rename to hw/bsp/mcx/boards/mcxn947brk/pin_mux.h diff --git a/hw/bsp/mcxa/debug.jlinkscript b/hw/bsp/mcx/debug.jlinkscript similarity index 100% rename from hw/bsp/mcxa/debug.jlinkscript rename to hw/bsp/mcx/debug.jlinkscript diff --git a/hw/bsp/mcxn/family.c b/hw/bsp/mcx/family.c similarity index 93% rename from hw/bsp/mcxn/family.c rename to hw/bsp/mcx/family.c index 8672ca63f..74b84773d 100644 --- a/hw/bsp/mcxn/family.c +++ b/hw/bsp/mcx/family.c @@ -52,6 +52,8 @@ //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ + +#if CFG_TUSB_MCU == OPT_MCU_MCXN9 void USB0_FS_IRQHandler(void) { tud_int_handler(0); @@ -62,6 +64,14 @@ void USB1_HS_IRQHandler(void) tud_int_handler(1); } +#elif CFG_TUSB_MCU == OPT_MCU_MCXA15 +void USB0_IRQHandler(void) +{ + tud_int_handler(0); +} +#endif + + void board_init(void) { BOARD_InitPins(); @@ -123,16 +133,28 @@ void board_init(void) // USB VBUS /* PORT0 PIN22 configured as USB0_VBUS */ -#if PORT_SUPPORT_DEVICE(0) + + /* MCXA15 USB configurations */ +#if PORT_SUPPORT_DEVICE(0) && (CFG_TUSB_MCU == OPT_MCU_MCXA15) + + RESET_PeripheralReset(kUSB0_RST_SHIFT_RSTn); + CLOCK_EnableUsbfsClock(); + +#endif + + + /* MCXN9 USB configurations */ +#if PORT_SUPPORT_DEVICE(0) && (CFG_TUSB_MCU == OPT_MCU_MCXN9) // Port0 is Full Speed CLOCK_AttachClk(kCLK_48M_to_USB0); CLOCK_EnableClock(kCLOCK_Usb0Ram); CLOCK_EnableClock(kCLOCK_Usb0Fs); CLOCK_EnableUsbfsClock(); + #endif -#if PORT_SUPPORT_DEVICE(1) +#if PORT_SUPPORT_DEVICE(1) && (CFG_TUSB_MCU == OPT_MCU_MCXN9) // Port1 is High Speed // Power diff --git a/hw/bsp/mcxn/family.cmake b/hw/bsp/mcx/family.cmake similarity index 85% rename from hw/bsp/mcxn/family.cmake rename to hw/bsp/mcx/family.cmake index 13d1d44ef..078d13b9f 100644 --- a/hw/bsp/mcxn/family.cmake +++ b/hw/bsp/mcx/family.cmake @@ -11,12 +11,8 @@ set(CMSIS_DIR ${TOP}/lib/CMSIS_5) include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up -set(CMAKE_SYSTEM_PROCESSOR cortex-m33 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) -set(FAMILY_MCUS MCXN9 CACHE INTERNAL "") - - #------------------------------------ # BOARD_TARGET #------------------------------------ @@ -31,12 +27,23 @@ function(add_board_target BOARD_TARGET) ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_gpio.c ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_common_arm.c ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_lpuart.c - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_lpflexcomm.c + # mcu ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_reset.c ${SDK_DIR}/devices/${MCU_VARIANT}/system_${MCU_CORE}.c ) + + if (${FAMILY_MCUS} STREQUAL "MCXN9") + target_sources(${BOARD_TARGET} PRIVATE + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_lpflexcomm.c + ) + elseif(${FAMILY_MCUS} STREQUAL "MCXA15") + target_sources(${BOARD_TARGET} PRIVATE + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_spc.c + ) + endif() + # target_compile_definitions(${BOARD_TARGET} PUBLIC # ) target_include_directories(${BOARD_TARGET} PUBLIC @@ -93,7 +100,12 @@ function(family_configure_example TARGET RTOS) ) # Add TinyUSB target and port source - family_add_tinyusb(${TARGET} OPT_MCU_MCXN9 ${RTOS}) + if (${FAMILY_MCUS} STREQUAL "MCXN9") + family_add_tinyusb(${TARGET} OPT_MCU_MCXN9 ${RTOS}) + elseif(${FAMILY_MCUS} STREQUAL "MCXA15") + family_add_tinyusb(${TARGET} OPT_MCU_MCXA15 ${RTOS}) + endif() + target_sources(${TARGET}-tinyusb PUBLIC # TinyUSB: Port0 is chipidea FS, Port1 is chipidea HS ${TOP}/src/portable/chipidea/$ diff --git a/hw/bsp/mcxn/family.mk b/hw/bsp/mcx/family.mk similarity index 83% rename from hw/bsp/mcxn/family.mk rename to hw/bsp/mcx/family.mk index 526effdfb..59170271c 100644 --- a/hw/bsp/mcxn/family.mk +++ b/hw/bsp/mcx/family.mk @@ -4,14 +4,12 @@ SDK_DIR = hw/mcu/nxp/mcux-sdk DEPS_SUBMODULES += $(SDK_DIR) lib/CMSIS_5 include $(TOP)/$(BOARD_PATH)/board.mk -CPU_CORE ?= cortex-m33 # Default to Highspeed PORT1 PORT ?= 1 CFLAGS += \ -flto \ - -DCFG_TUSB_MCU=OPT_MCU_MCXN9 \ -DBOARD_TUD_RHPORT=$(PORT) \ # mcu driver cause following warnings @@ -38,9 +36,25 @@ SRC_C += \ $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_clock.c \ $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_reset.c \ $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_gpio.c \ - $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_common_arm.c \ - $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_lpflexcomm.c \ $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_lpuart.c \ + $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_common_arm.c \ + + +# fsl_lpflexcomm just needed for MCXN9 +ifeq ($(MCU_VARIANT), MCXN947) + SRC_C += \ + $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_lpflexcomm.c \ + +endif + +# fsl_spc just needed for MCXNA15 +ifeq ($(MCU_VARIANT), MCXA153) + SRC_C += \ + $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_spc.c \ + +endif + + INC += \ $(TOP)/$(BOARD_PATH) \ diff --git a/hw/bsp/mcxa/family.c b/hw/bsp/mcxa/family.c deleted file mode 100644 index d2bc35f8c..000000000 --- a/hw/bsp/mcxa/family.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2018, 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. - * - * This file is part of the TinyUSB stack. - */ - -#include "bsp/board_api.h" -#include "fsl_device_registers.h" -#include "fsl_gpio.h" -#include "fsl_lpuart.h" -#include "board.h" - -#include "pin_mux.h" -#include "clock_config.h" - - -#ifdef BOARD_TUD_RHPORT - #define PORT_SUPPORT_DEVICE(_n) (BOARD_TUD_RHPORT == _n) -#else - #define PORT_SUPPORT_DEVICE(_n) 0 -#endif - -#ifdef BOARD_TUH_RHPORT - #define PORT_SUPPORT_HOST(_n) (BOARD_TUH_RHPORT == _n) -#else - #define PORT_SUPPORT_HOST(_n) 0 -#endif - -//--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM -//--------------------------------------------------------------------+ - -//--------------------------------------------------------------------+ -// Forward USB interrupt events to TinyUSB IRQ Handler -//--------------------------------------------------------------------+ -void USB0_IRQHandler(void) -{ - tud_int_handler(0); -} - -void board_init(void) -{ - BOARD_InitPins(); - BOARD_InitBootClocks(); - CLOCK_SetupExtClocking(XTAL0_CLK_HZ); - - // 1ms tick timer - SysTick_Config(SystemCoreClock / 1000); - - // LED - CLOCK_EnableClock(LED_CLK); - gpio_pin_config_t LED_RED_config = { - .pinDirection = kGPIO_DigitalOutput, - .outputLogic = 0U - }; - - /* Initialize GPIO functionality on pin PIO3_12 (pin 38) */ - GPIO_PinInit(LED_GPIO, LED_PIN, &LED_RED_config); - board_led_write(1); - - // Button -#ifdef BUTTON_GPIO - CLOCK_EnableClock(BUTTON_CLK); - gpio_pin_config_t const button_config = { kGPIO_DigitalInput, 0}; - GPIO_PinInit(BUTTON_GPIO, BUTTON_PIN, &button_config); -#endif - -#ifdef UART_DEV - - CLOCK_SetClockDiv(kCLOCK_DivLPUART0, 1u); - CLOCK_AttachClk(kFRO12M_to_LPUART0); - RESET_PeripheralReset(kLPUART0_RST_SHIFT_RSTn); - - lpuart_config_t uart_config; - LPUART_GetDefaultConfig(&uart_config); - uart_config.baudRate_Bps = 115200; - uart_config.enableTx = true; - uart_config.enableRx = false; - LPUART_Init(UART_DEV, &uart_config, 12000000u); - - -#endif - - // USB VBUS - /* PORT0 PIN22 configured as USB0_VBUS */ - -#if PORT_SUPPORT_DEVICE(0) - RESET_PeripheralReset(kUSB0_RST_SHIFT_RSTn); - CLOCK_EnableUsbfsClock(); -#endif - -} - -//--------------------------------------------------------------------+ -// 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_GPIO - return BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_GPIO, BUTTON_PIN); -#else - return 1; -#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 - LPUART_WriteBlocking(UART_DEV, (uint8_t const *) buf, 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 - \ No newline at end of file diff --git a/hw/bsp/mcxa/family.cmake b/hw/bsp/mcxa/family.cmake deleted file mode 100644 index d2b2321d6..000000000 --- a/hw/bsp/mcxa/family.cmake +++ /dev/null @@ -1,110 +0,0 @@ -include_guard() - -if (NOT BOARD) - message(FATAL_ERROR "BOARD not specified") -endif () - -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-m33-nodsp-nofp CACHE INTERNAL "System Processor") -set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) - -set(FAMILY_MCUS MCXA CACHE INTERNAL "") - - -#------------------------------------ -# BOARD_TARGET -#------------------------------------ -# only need to be built ONCE for all examples -function(add_board_target BOARD_TARGET) - if (NOT TARGET ${BOARD_TARGET}) - add_library(${BOARD_TARGET} STATIC - # external driver - #lib/sct_neopixel/sct_neopixel.c - - # driver - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_gpio.c - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_common_arm.c - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_lpuart.c - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_spc.c - # mcu - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_reset.c - ${SDK_DIR}/devices/${MCU_VARIANT}/system_${MCU_CORE}.c - ) - # target_compile_definitions(${BOARD_TARGET} PUBLIC - # ) - target_include_directories(${BOARD_TARGET} PUBLIC - # driver - # mcu - ${CMSIS_DIR}/CMSIS/Core/Include - ${SDK_DIR}/devices/${MCU_VARIANT} - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers - ) - - update_board(${BOARD_TARGET}) - - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - target_sources(${BOARD_TARGET} PUBLIC - ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_CORE}.S - ) - target_link_options(${BOARD_TARGET} PUBLIC - # linker file - "LINKER:--script=${SDK_DIR}/devices/${MCU_VARIANT}/gcc/${MCU_CORE}_flash.ld" - # nanolib - --specs=nosys.specs - --specs=nano.specs - ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--config=${LD_FILE_IAR}" - ) - endif () - 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_MCXA ${RTOS}) - target_sources(${TARGET}-tinyusb PUBLIC - # TinyUSB: Port0 is chipidea FS, Port1 is chipidea HS - ${TOP}/src/portable/chipidea/ci_fs/dcd_ci_fs.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}) - #family_flash_nxplink(${TARGET}) - #family_flash_pyocd(${TARGET}) -endfunction() diff --git a/hw/bsp/mcxa/family.mk b/hw/bsp/mcxa/family.mk deleted file mode 100644 index 87ae92fab..000000000 --- a/hw/bsp/mcxa/family.mk +++ /dev/null @@ -1,42 +0,0 @@ -UF2_FAMILY_ID = 0x2abc77ec -SDK_DIR = hw/mcu/nxp/mcux-sdk - -DEPS_SUBMODULES += $(SDK_DIR) lib/CMSIS_5 #not found - -include $(TOP)/$(BOARD_PATH)/board.mk -CPU_CORE ?= cortex-m33-nodsp-nofp - -CFLAGS += \ - -flto \ - -DCFG_TUSB_MCU=OPT_MCU_MCXA \ - -DBOARD_TUD_RHPORT=0 - -# mcu driver cause following warnings -CFLAGS += -Wno-error=unused-parameter -Wno-error=old-style-declaration - -LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs - -# All source paths should be relative to the top level. -LD_FILE ?= $(SDK_DIR)/devices/$(MCU_VARIANT)/gcc/$(MCU_CORE)_flash.ld - -# TinyUSB: Port0 is chipidea FS, Port1 is chipidea HS -$(info "PORT0 Full Speed") -CFLAGS += -DBOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED -SRC_C += src/portable/chipidea/ci_fs/dcd_ci_fs.c - -SRC_C += \ - $(SDK_DIR)/devices/$(MCU_VARIANT)/system_$(MCU_CORE).c \ - $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_clock.c \ - $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_reset.c \ - $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_gpio.c \ - $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_lpuart.c \ - $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_common_arm.c \ - $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_spc.c -INC += \ - $(TOP)/$(BOARD_PATH) \ - $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ - $(TOP)/$(SDK_DIR)/devices/$(MCU_VARIANT) \ - $(TOP)/$(SDK_DIR)/devices/$(MCU_VARIANT)/drivers - - -SRC_S += $(SDK_DIR)/devices/$(MCU_VARIANT)/gcc/startup_$(MCU_CORE).S diff --git a/hw/bsp/mcxn/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/mcxn/FreeRTOSConfig/FreeRTOSConfig.h deleted file mode 100644 index 6f10a7ab0..000000000 --- a/hw/bsp/mcxn/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 "fsl_device_registers.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: Thu, 22 Feb 2024 19:20:28 +0700 Subject: [PATCH 119/454] slightly change cdc_msc_freertos example --- examples/device/cdc_msc_freertos/src/main.c | 51 +++++++++++---------- src/class/video/video.h | 6 ++- 2 files changed, 32 insertions(+), 25 deletions(-) diff --git a/examples/device/cdc_msc_freertos/src/main.c b/examples/device/cdc_msc_freertos/src/main.c index 1dadc4513..e94e8eaec 100644 --- a/examples/device/cdc_msc_freertos/src/main.c +++ b/examples/device/cdc_msc_freertos/src/main.c @@ -52,7 +52,8 @@ #define USBD_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1) #endif -#define CDC_STACK_SZIE configMINIMAL_STACK_SIZE +#define CDC_STACK_SIZE configMINIMAL_STACK_SIZE +#define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTOTYPES @@ -69,21 +70,22 @@ enum { BLINK_SUSPENDED = 2500, }; -// static timer & task +// static task #if configSUPPORT_STATIC_ALLOCATION -StaticTimer_t blinky_tmdef; +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 cdc_stack[CDC_STACK_SZIE]; +StackType_t cdc_stack[CDC_STACK_SIZE]; StaticTask_t cdc_taskdef; #endif -TimerHandle_t blinky_tm; +static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; -static void led_blinky_cb(TimerHandle_t xTimer); static void usb_device_task(void *param); +void led_blinking_task(void* param); void cdc_task(void *params); //--------------------------------------------------------------------+ @@ -94,22 +96,20 @@ int main(void) { board_init(); #if configSUPPORT_STATIC_ALLOCATION - // soft timer for blinky - blinky_tm = xTimerCreateStatic(NULL, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), true, NULL, led_blinky_cb, &blinky_tmdef); + // 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 CDC task - xTaskCreateStatic(cdc_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES-2, cdc_stack, &cdc_taskdef); + xTaskCreateStatic(cdc_task, "cdc", CDC_STACK_SIZE, NULL, configMAX_PRIORITIES - 2, cdc_stack, &cdc_taskdef); #else - blinky_tm = xTimerCreate(NULL, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), true, NULL, led_blinky_cb); + 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(cdc_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES - 2, NULL); #endif - 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) vTaskStartScheduler(); @@ -154,12 +154,12 @@ static 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 @@ -167,16 +167,12 @@ void tud_umount_cb(void) { // 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); + blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed void tud_resume_cb(void) { - if (tud_mounted()) { - xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_MOUNTED), 0); - } else { - xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), 0); - } + blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ @@ -235,10 +231,17 @@ void tud_cdc_rx_cb(uint8_t itf) { //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ -static 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/src/class/video/video.h b/src/class/video/video.h index 6319c6536..abf1e34b9 100644 --- a/src/class/video/video.h +++ b/src/class/video/video.h @@ -368,6 +368,8 @@ typedef struct TU_ATTR_PACKED { uint8_t bCopyProtect; } tusb_desc_video_format_uncompressed_t; +TU_VERIFY_STATIC(sizeof(tusb_desc_video_format_uncompressed_t) == 27, "size is not correct"); + // Uncompressed payload specs: 3.1.2 frame descriptor #define tusb_desc_video_frame_uncompressed_nint_t(_nint) \ struct TU_ATTR_PACKED { \ @@ -381,7 +383,7 @@ typedef struct TU_ATTR_PACKED { uint32_t dwMinBitRate; \ uint32_t dwMaxBitRate; \ uint32_t dwMaxVideoFrameBufferSize; /* deprecated in 1.5 */ \ - uint32_t dwDefaultFrameInterval; \ + uint32_t dwDefaultFrameInterval; /* 100ns unit */\ uint8_t bFrameIntervalType; \ uint32_t dwFrameInterval[_nint]; \ } @@ -413,6 +415,8 @@ typedef struct TU_ATTR_PACKED { uint8_t bCopyProtect; } tusb_desc_video_format_mjpeg_t; +TU_VERIFY_STATIC(sizeof(tusb_desc_video_format_mjpeg_t) == 11, "size is not correct"); + // MJPEG payload specs: 3.1.2 frame descriptor (same as uncompressed) typedef tusb_desc_video_frame_uncompressed_t tusb_desc_video_frame_mjpeg_t; typedef tusb_desc_video_frame_uncompressed_1int_t tusb_desc_video_frame_mjpeg_1int_t; From ec91660119c6ce4ccc6aa011f2c6cc9869ab9410 Mon Sep 17 00:00:00 2001 From: Jerry Palacios Date: Thu, 22 Feb 2024 16:11:23 -0600 Subject: [PATCH 120/454] Revert "Merge branch 'hathach:master' into MCX" This reverts commit 6afd4a57896f9c9e794de3ab6eabc73d18be4bd0, reversing changes made to 5c14bd13da211ff2679115b0dba96ac80c1a516c. --- examples/device/cdc_msc_freertos/src/main.c | 51 +- .../boards/frdm_k32l2a4s/board.mk | 3 + .../boards/frdm_k32l2a4s/clock_config.c | 491 ------------------ .../boards/frdm_k32l2a4s/clock_config.h | 164 ------ .../kinetis_k32l2/boards/frdm_k32l2b/board.mk | 3 + .../boards/frdm_k32l2b/clock_config.c | 220 -------- .../boards/frdm_k32l2b/clock_config.h | 110 ---- hw/bsp/nrf/boards/pca10095/board.cmake | 3 - hw/bsp/nrf/boards/pca10095/board.h | 4 +- hw/bsp/nrf/boards/pca10095/board.mk | 3 - hw/bsp/nrf/family.c | 1 - src/class/msc/msc_device.c | 2 +- src/class/video/video.h | 6 +- src/class/video/video_device.c | 1 - src/common/tusb_debug.h | 3 +- src/common/tusb_fifo.c | 1 - src/device/usbd.c | 1 + src/host/usbh.c | 22 +- src/host/usbh_pvt.h | 6 +- src/portable/nordic/nrf5x/dcd_nrf5x.c | 8 +- src/portable/ohci/ohci.h | 2 +- 21 files changed, 52 insertions(+), 1053 deletions(-) delete mode 100644 hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/clock_config.c delete mode 100644 hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/clock_config.h delete mode 100644 hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.c delete mode 100644 hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.h diff --git a/examples/device/cdc_msc_freertos/src/main.c b/examples/device/cdc_msc_freertos/src/main.c index e94e8eaec..1dadc4513 100644 --- a/examples/device/cdc_msc_freertos/src/main.c +++ b/examples/device/cdc_msc_freertos/src/main.c @@ -52,8 +52,7 @@ #define USBD_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1) #endif -#define CDC_STACK_SIZE configMINIMAL_STACK_SIZE -#define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE +#define CDC_STACK_SZIE configMINIMAL_STACK_SIZE //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTOTYPES @@ -70,22 +69,21 @@ enum { BLINK_SUSPENDED = 2500, }; -// static task +// static timer & task #if configSUPPORT_STATIC_ALLOCATION -StackType_t blinky_stack[BLINKY_STACK_SIZE]; -StaticTask_t blinky_taskdef; +StaticTimer_t blinky_tmdef; StackType_t usb_device_stack[USBD_STACK_SIZE]; StaticTask_t usb_device_taskdef; -StackType_t cdc_stack[CDC_STACK_SIZE]; +StackType_t cdc_stack[CDC_STACK_SZIE]; StaticTask_t cdc_taskdef; #endif -static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; +TimerHandle_t blinky_tm; +static void led_blinky_cb(TimerHandle_t xTimer); static void usb_device_task(void *param); -void led_blinking_task(void* param); void cdc_task(void *params); //--------------------------------------------------------------------+ @@ -96,20 +94,22 @@ int main(void) { board_init(); #if configSUPPORT_STATIC_ALLOCATION - // blinky task - xTaskCreateStatic(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, blinky_stack, &blinky_taskdef); + // soft timer for blinky + blinky_tm = xTimerCreateStatic(NULL, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), true, NULL, led_blinky_cb, &blinky_tmdef); // 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 CDC task - xTaskCreateStatic(cdc_task, "cdc", CDC_STACK_SIZE, NULL, configMAX_PRIORITIES - 2, cdc_stack, &cdc_taskdef); + xTaskCreateStatic(cdc_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES-2, cdc_stack, &cdc_taskdef); #else - xTaskCreate(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, NULL); + blinky_tm = xTimerCreate(NULL, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), true, NULL, led_blinky_cb); xTaskCreate(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL); xTaskCreate(cdc_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES - 2, NULL); #endif + 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) vTaskStartScheduler(); @@ -154,12 +154,12 @@ static void usb_device_task(void *param) { // Invoked when device is mounted void tud_mount_cb(void) { - blink_interval_ms = BLINK_MOUNTED; + xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_MOUNTED), 0); } // Invoked when device is unmounted void tud_umount_cb(void) { - blink_interval_ms = BLINK_NOT_MOUNTED; + xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), 0); } // Invoked when usb bus is suspended @@ -167,12 +167,16 @@ void tud_umount_cb(void) { // 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; + xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_SUSPENDED), 0); } // Invoked when usb bus is resumed void tud_resume_cb(void) { - blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; + if (tud_mounted()) { + xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_MOUNTED), 0); + } else { + xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), 0); + } } //--------------------------------------------------------------------+ @@ -231,17 +235,10 @@ void tud_cdc_rx_cb(uint8_t itf) { //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ -void led_blinking_task(void* param) { - (void) param; - static uint32_t start_ms = 0; +static void led_blinky_cb(TimerHandle_t xTimer) { + (void) xTimer; static bool led_state = false; - 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 - } + board_led_write(led_state); + led_state = 1 - led_state; // toggle } diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/board.mk b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/board.mk index c4dc65b63..f69700139 100644 --- a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/board.mk +++ b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/board.mk @@ -8,6 +8,9 @@ CFLAGS += -Wno-error=unused-parameter -Wno-error=redundant-decls -Wno-error=cast # All source paths should be relative to the top level. LD_FILE = $(MCU_DIR)/gcc/K32L2A41xxxxA_flash.ld +SRC_C += \ + $(MCU_DIR)/project_template/clock_config.c \ + # For flash-jlink target JLINK_DEVICE = K32L2A41xxxxA diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/clock_config.c b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/clock_config.c deleted file mode 100644 index 2814efc86..000000000 --- a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/clock_config.c +++ /dev/null @@ -1,491 +0,0 @@ -/* - * Copyright 2019 ,2021 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/*********************************************************************************************************************** - * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file - * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. - **********************************************************************************************************************/ -/* - * How to setup clock using clock driver functions: - * - * 1. Call CLOCK_InitXXX() to configure corresponding SCG clock source. - * Note: The clock could not be set when it is being used as system clock. - * In default out of reset, the CPU is clocked from FIRC(IRC48M), - * so before setting FIRC, change to use another available clock source. - * - * 2. Call CLOCK_SetXtal0Freq() to set XTAL0 frequency based on board settings. - * - * 3. Call CLOCK_SetXxxModeSysClkConfig() to set SCG mode for Xxx run mode. - * Wait until the system clock source is changed to target source. - * - * 4. If power mode change is needed, call SMC_SetPowerModeProtection() to allow - * corresponding power mode and SMC_SetPowerModeXxx() to change to Xxx mode. - * Supported run mode and clock restrictions could be found in Reference Manual. - */ - -/* clang-format off */ -/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* -!!GlobalInfo -product: Clocks v7.0 -processor: K32L2A41xxxxA -package_id: K32L2A41VLL1A -mcu_data: ksdk2_0 -processor_version: 9.0.0 - * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ -/* clang-format on */ - -#include "fsl_smc.h" -#include "clock_config.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ -#define SCG_CLKOUTCNFG_SIRC 2U /*!< SCG CLKOUT clock select: Slow IRC */ -#define SCG_SOSC_DISABLE 0U /*!< System OSC disabled */ -#define SCG_SPLL_DISABLE 0U /*!< System PLL disabled */ -#define SCG_SYS_OSC_CAP_0P 0U /*!< Oscillator 0pF capacitor load */ - -/******************************************************************************* - * Variables - ******************************************************************************/ -/* System clock frequency. */ -extern uint32_t SystemCoreClock; - -/******************************************************************************* - * Code - ******************************************************************************/ -/*FUNCTION********************************************************************** - * - * Function Name : CLOCK_CONFIG_SetScgOutSel - * Description : Set the SCG clock out select (CLKOUTSEL). - * Param setting : The selected clock source. - * - *END**************************************************************************/ -static void CLOCK_CONFIG_SetScgOutSel(uint8_t setting) -{ - SCG->CLKOUTCNFG = SCG_CLKOUTCNFG_CLKOUTSEL(setting); -} - -/*FUNCTION********************************************************************** - * - * Function Name : CLOCK_CONFIG_FircSafeConfig - * Description : This function is used to safely configure FIRC clock. - * In default out of reset, the CPU is clocked from FIRC(IRC48M). - * Before setting FIRC, change to use SIRC as system clock, - * then configure FIRC. After FIRC is set, change back to use FIRC - * in case SIRC need to be configured. - * Param fircConfig : FIRC configuration. - * - *END**************************************************************************/ -static void CLOCK_CONFIG_FircSafeConfig(const scg_firc_config_t *fircConfig) -{ - scg_sys_clk_config_t curConfig; - const scg_sirc_config_t scgSircConfig = {.enableMode = kSCG_SircEnable, - .div1 = kSCG_AsyncClkDisable, - .div3 = kSCG_AsyncClkDivBy2, - .range = kSCG_SircRangeHigh}; - scg_sys_clk_config_t sysClkSafeConfigSource = { - .divSlow = kSCG_SysClkDivBy4, /* Slow clock divider */ -#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) - .reserved1 = 0, - .reserved2 = 0, - .reserved3 = 0, -#endif - .divCore = kSCG_SysClkDivBy1, /* Core clock divider */ -#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) - .reserved4 = 0, -#endif - .src = kSCG_SysClkSrcSirc, /* System clock source */ -#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) - .reserved5 = 0, -#endif - }; - /* Init Sirc. */ - CLOCK_InitSirc(&scgSircConfig); - /* Change to use SIRC as system clock source to prepare to change FIRCCFG register. */ - CLOCK_SetRunModeSysClkConfig(&sysClkSafeConfigSource); - /* Wait for clock source switch finished. */ - do - { - CLOCK_GetCurSysClkConfig(&curConfig); - } while (curConfig.src != sysClkSafeConfigSource.src); - - /* Init Firc. */ - CLOCK_InitFirc(fircConfig); - /* Change back to use FIRC as system clock source in order to configure SIRC if needed. */ - sysClkSafeConfigSource.src = kSCG_SysClkSrcFirc; - CLOCK_SetRunModeSysClkConfig(&sysClkSafeConfigSource); - /* Wait for clock source switch finished. */ - do - { - CLOCK_GetCurSysClkConfig(&curConfig); - } while (curConfig.src != sysClkSafeConfigSource.src); -} - -/******************************************************************************* - ************************ BOARD_InitBootClocks function ************************ - ******************************************************************************/ -void BOARD_InitBootClocks(void) -{ - BOARD_BootClockRUN(); -} - -/******************************************************************************* - ********************** Configuration BOARD_BootClockRUN *********************** - ******************************************************************************/ -/* clang-format off */ -/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* -!!Configuration -name: BOARD_BootClockRUN -called_from_default_init: true -outputs: -- {id: Core_clock.outFreq, value: 48 MHz} -- {id: FIRCDIV1_CLK.outFreq, value: 48 MHz} -- {id: FIRCDIV3_CLK.outFreq, value: 48 MHz} -- {id: LPO_clock.outFreq, value: 1 kHz} -- {id: OSC32KCLK.outFreq, value: 32.768 kHz} -- {id: SIRCDIV3_CLK.outFreq, value: 4 MHz} -- {id: SIRC_CLK.outFreq, value: 8 MHz} -- {id: SOSCDIV3_CLK.outFreq, value: 32.768 kHz} -- {id: SOSCER_CLK.outFreq, value: 32.768 kHz} -- {id: SOSC_CLK.outFreq, value: 32.768 kHz} -- {id: Slow_clock.outFreq, value: 24 MHz} -- {id: System_clock.outFreq, value: 48 MHz} -settings: -- {id: SCG.FIRCDIV1.scale, value: '1', locked: true} -- {id: SCG.FIRCDIV3.scale, value: '1', locked: true} -- {id: SCG.SIRCDIV3.scale, value: '2', locked: true} -- {id: SCG.SOSCDIV3.scale, value: '1', locked: true} -- {id: SCG_SOSCCFG_OSC_MODE_CFG, value: ModeOscLowPower} -- {id: SCG_SOSCCSR_SOSCEN_CFG, value: Enabled} -- {id: SCG_SOSCCSR_SOSCERCLKEN_CFG, value: Enabled} -sources: -- {id: SCG.SOSC.outFreq, value: 32.768 kHz, enabled: true} - * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ -/* clang-format on */ - -/******************************************************************************* - * Variables for BOARD_BootClockRUN configuration - ******************************************************************************/ -const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockRUN = - { - .divSlow = kSCG_SysClkDivBy2, /* Slow Clock Divider: divided by 2 */ -#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) - .reserved1 = 0, - .reserved2 = 0, - .reserved3 = 0, -#endif - .divCore = kSCG_SysClkDivBy1, /* Core Clock Divider: divided by 1 */ -#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) - .reserved4 = 0, -#endif - .src = kSCG_SysClkSrcFirc, /* Fast IRC is selected as System Clock Source */ -#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) - .reserved5 = 0, -#endif - }; -const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockRUN = - { - .freq = 32768U, /* System Oscillator frequency: 32768Hz */ - .enableMode = kSCG_SysOscEnable | kSCG_SysOscEnableErClk,/* Enable System OSC clock, Enable OSCERCLK */ - .monitorMode = kSCG_SysOscMonitorDisable, /* Monitor disabled */ - .div1 = kSCG_AsyncClkDisable, /* System OSC Clock Divider 1: Clock output is disabled */ - .div3 = kSCG_AsyncClkDivBy1, /* System OSC Clock Divider 3: divided by 1 */ - .capLoad = SCG_SYS_OSC_CAP_0P, /* Oscillator capacity load: 0pF */ - .workMode = kSCG_SysOscModeOscLowPower, /* Oscillator low power */ - }; -const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockRUN = - { - .enableMode = kSCG_SircEnable | kSCG_SircEnableInLowPower,/* Enable SIRC clock, Enable SIRC in low power mode */ - .div1 = kSCG_AsyncClkDisable, /* Slow IRC Clock Divider 1: Clock output is disabled */ - .div3 = kSCG_AsyncClkDivBy2, /* Slow IRC Clock Divider 3: divided by 2 */ - .range = kSCG_SircRangeHigh, /* Slow IRC high range clock (8 MHz) */ - }; -const scg_firc_config_t g_scgFircConfig_BOARD_BootClockRUN = - { - .enableMode = kSCG_FircEnable, /* Enable FIRC clock */ - .div1 = kSCG_AsyncClkDivBy1, /* Fast IRC Clock Divider 1: divided by 1 */ - .div3 = kSCG_AsyncClkDivBy1, /* Fast IRC Clock Divider 3: divided by 1 */ - .range = kSCG_FircRange48M, /* Fast IRC is trimmed to 48MHz */ - .trimConfig = NULL, /* Fast IRC Trim disabled */ - }; -const scg_spll_config_t g_scgSysPllConfig_BOARD_BootClockRUN = - { - .enableMode = SCG_SPLL_DISABLE, /* System PLL disabled */ - .monitorMode = kSCG_SysPllMonitorDisable, /* Monitor disabled */ - .div1 = kSCG_AsyncClkDisable, /* System PLL Clock Divider 1: Clock output is disabled */ - .div3 = kSCG_AsyncClkDisable, /* System PLL Clock Divider 3: Clock output is disabled */ - .src = kSCG_SysPllSrcSysOsc, /* System PLL clock source is System OSC */ - .prediv = 0, /* Divided by 1 */ - .mult = 0, /* Multiply Factor is 16 */ - }; -/******************************************************************************* - * Code for BOARD_BootClockRUN configuration - ******************************************************************************/ -void BOARD_BootClockRUN(void) -{ - scg_sys_clk_config_t curConfig; - - /* Init SOSC according to board configuration. */ - CLOCK_InitSysOsc(&g_scgSysOscConfig_BOARD_BootClockRUN); - /* Set the XTAL0 frequency based on board settings. */ - CLOCK_SetXtal0Freq(g_scgSysOscConfig_BOARD_BootClockRUN.freq); - /* Init FIRC. */ - CLOCK_CONFIG_FircSafeConfig(&g_scgFircConfig_BOARD_BootClockRUN); - /* Init SIRC. */ - CLOCK_InitSirc(&g_scgSircConfig_BOARD_BootClockRUN); - /* Set SCG to FIRC mode. */ - CLOCK_SetRunModeSysClkConfig(&g_sysClkConfig_BOARD_BootClockRUN); - /* Wait for clock source switch finished. */ - do - { - CLOCK_GetCurSysClkConfig(&curConfig); - } while (curConfig.src != g_sysClkConfig_BOARD_BootClockRUN.src); - /* Set SystemCoreClock variable. */ - SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; -} - -/******************************************************************************* - ********************* Configuration BOARD_BootClockHSRUN ********************** - ******************************************************************************/ -/* clang-format off */ -/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* -!!Configuration -name: BOARD_BootClockHSRUN -outputs: -- {id: CLKOUT.outFreq, value: 8 MHz} -- {id: Core_clock.outFreq, value: 96 MHz, locked: true, accuracy: '0.001'} -- {id: FIRCDIV1_CLK.outFreq, value: 48 MHz} -- {id: FIRCDIV3_CLK.outFreq, value: 48 MHz} -- {id: LPO_clock.outFreq, value: 1 kHz} -- {id: OSC32KCLK.outFreq, value: 32.768 kHz} -- {id: PLLDIV1_CLK.outFreq, value: 96 MHz} -- {id: PLLDIV3_CLK.outFreq, value: 96 MHz} -- {id: SIRCDIV1_CLK.outFreq, value: 8 MHz} -- {id: SIRCDIV3_CLK.outFreq, value: 8 MHz} -- {id: SIRC_CLK.outFreq, value: 8 MHz} -- {id: SOSCDIV1_CLK.outFreq, value: 32.768 kHz} -- {id: SOSCDIV3_CLK.outFreq, value: 32.768 kHz} -- {id: SOSCER_CLK.outFreq, value: 32.768 kHz} -- {id: SOSC_CLK.outFreq, value: 32.768 kHz} -- {id: Slow_clock.outFreq, value: 24 MHz, locked: true, accuracy: '0.001'} -- {id: System_clock.outFreq, value: 96 MHz} -settings: -- {id: SCGMode, value: SPLL} -- {id: powerMode, value: HSRUN} -- {id: CLKOUTConfig, value: 'yes'} -- {id: SCG.DIVSLOW.scale, value: '4'} -- {id: SCG.FIRCDIV1.scale, value: '1', locked: true} -- {id: SCG.FIRCDIV3.scale, value: '1', locked: true} -- {id: SCG.PREDIV.scale, value: '4'} -- {id: SCG.SCSSEL.sel, value: SCG.SPLL_DIV2_CLK} -- {id: SCG.SIRCDIV1.scale, value: '1', locked: true} -- {id: SCG.SIRCDIV3.scale, value: '1', locked: true} -- {id: SCG.SOSCDIV1.scale, value: '1', locked: true} -- {id: SCG.SOSCDIV3.scale, value: '1', locked: true} -- {id: SCG.SPLLDIV1.scale, value: '1', locked: true} -- {id: SCG.SPLLDIV3.scale, value: '1', locked: true} -- {id: SCG.SPLLSRCSEL.sel, value: SCG.FIRC} -- {id: SCG_SOSCCFG_OSC_MODE_CFG, value: ModeOscLowPower} -- {id: SCG_SOSCCSR_SOSCEN_CFG, value: Enabled} -- {id: SCG_SOSCCSR_SOSCERCLKEN_CFG, value: Enabled} -- {id: SCG_SPLLCSR_SPLLEN_CFG, value: Enabled} -sources: -- {id: SCG.SOSC.outFreq, value: 32.768 kHz, enabled: true} - * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ -/* clang-format on */ - -/******************************************************************************* - * Variables for BOARD_BootClockHSRUN configuration - ******************************************************************************/ -const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockHSRUN = - { - .divSlow = kSCG_SysClkDivBy4, /* Slow Clock Divider: divided by 4 */ -#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) - .reserved1 = 0, - .reserved2 = 0, - .reserved3 = 0, -#endif - .divCore = kSCG_SysClkDivBy1, /* Core Clock Divider: divided by 1 */ -#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) - .reserved4 = 0, -#endif - .src = kSCG_SysClkSrcSysPll, /* System PLL is selected as System Clock Source */ -#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) - .reserved5 = 0, -#endif - }; -const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockHSRUN = - { - .freq = 32768U, /* System Oscillator frequency: 32768Hz */ - .enableMode = kSCG_SysOscEnable | kSCG_SysOscEnableErClk,/* Enable System OSC clock, Enable OSCERCLK */ - .monitorMode = kSCG_SysOscMonitorDisable, /* Monitor disabled */ - .div1 = kSCG_AsyncClkDivBy1, /* System OSC Clock Divider 1: divided by 1 */ - .div3 = kSCG_AsyncClkDivBy1, /* System OSC Clock Divider 3: divided by 1 */ - .capLoad = SCG_SYS_OSC_CAP_0P, /* Oscillator capacity load: 0pF */ - .workMode = kSCG_SysOscModeOscLowPower, /* Oscillator low power */ - }; -const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockHSRUN = - { - .enableMode = kSCG_SircEnable | kSCG_SircEnableInLowPower,/* Enable SIRC clock, Enable SIRC in low power mode */ - .div1 = kSCG_AsyncClkDivBy1, /* Slow IRC Clock Divider 1: divided by 1 */ - .div3 = kSCG_AsyncClkDivBy1, /* Slow IRC Clock Divider 3: divided by 1 */ - .range = kSCG_SircRangeHigh, /* Slow IRC high range clock (8 MHz) */ - }; -const scg_firc_config_t g_scgFircConfig_BOARD_BootClockHSRUN = - { - .enableMode = kSCG_FircEnable, /* Enable FIRC clock */ - .div1 = kSCG_AsyncClkDivBy1, /* Fast IRC Clock Divider 1: divided by 1 */ - .div3 = kSCG_AsyncClkDivBy1, /* Fast IRC Clock Divider 3: divided by 1 */ - .range = kSCG_FircRange48M, /* Fast IRC is trimmed to 48MHz */ - .trimConfig = NULL, /* Fast IRC Trim disabled */ - }; -const scg_spll_config_t g_scgSysPllConfig_BOARD_BootClockHSRUN = - { - .enableMode = kSCG_SysPllEnable, /* Enable SPLL clock */ - .monitorMode = kSCG_SysPllMonitorDisable, /* Monitor disabled */ - .div1 = kSCG_AsyncClkDivBy1, /* System PLL Clock Divider 1: divided by 1 */ - .div3 = kSCG_AsyncClkDivBy1, /* System PLL Clock Divider 3: divided by 1 */ - .src = kSCG_SysPllSrcFirc, /* System PLL clock source is Fast IRC */ - .prediv = 3, /* Divided by 4 */ - .mult = 0, /* Multiply Factor is 16 */ - }; -/******************************************************************************* - * Code for BOARD_BootClockHSRUN configuration - ******************************************************************************/ -void BOARD_BootClockHSRUN(void) -{ - scg_sys_clk_config_t curConfig; - - /* Init SOSC according to board configuration. */ - CLOCK_InitSysOsc(&g_scgSysOscConfig_BOARD_BootClockHSRUN); - /* Set the XTAL0 frequency based on board settings. */ - CLOCK_SetXtal0Freq(g_scgSysOscConfig_BOARD_BootClockHSRUN.freq); - /* Init FIRC. */ - CLOCK_CONFIG_FircSafeConfig(&g_scgFircConfig_BOARD_BootClockHSRUN); - /* Init SIRC. */ - CLOCK_InitSirc(&g_scgSircConfig_BOARD_BootClockHSRUN); - /* Init SysPll. */ - CLOCK_InitSysPll(&g_scgSysPllConfig_BOARD_BootClockHSRUN); - /* Set HSRUN power mode. */ - SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll); - SMC_SetPowerModeHsrun(SMC); - while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateHsrun) - { - } - - /* Set SCG to SPLL mode. */ - CLOCK_SetHsrunModeSysClkConfig(&g_sysClkConfig_BOARD_BootClockHSRUN); - /* Wait for clock source switch finished. */ - do - { - CLOCK_GetCurSysClkConfig(&curConfig); - } while (curConfig.src != g_sysClkConfig_BOARD_BootClockHSRUN.src); - /* Set SystemCoreClock variable. */ - SystemCoreClock = BOARD_BOOTCLOCKHSRUN_CORE_CLOCK; - /* Set SCG CLKOUT selection. */ - CLOCK_CONFIG_SetScgOutSel(SCG_CLKOUTCNFG_SIRC); -} - -/******************************************************************************* - ********************* Configuration BOARD_BootClockVLPR *********************** - ******************************************************************************/ -/* clang-format off */ -/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* -!!Configuration -name: BOARD_BootClockVLPR -outputs: -- {id: Core_clock.outFreq, value: 8 MHz, locked: true, accuracy: '0.001'} -- {id: LPO_clock.outFreq, value: 1 kHz} -- {id: SIRC_CLK.outFreq, value: 8 MHz} -- {id: Slow_clock.outFreq, value: 1 MHz, locked: true, accuracy: '0.001'} -- {id: System_clock.outFreq, value: 8 MHz} -settings: -- {id: SCGMode, value: SIRC} -- {id: powerMode, value: VLPR} -- {id: SCG.DIVSLOW.scale, value: '8'} -- {id: SCG.SCSSEL.sel, value: SCG.SIRC} -- {id: SCG_FIRCCSR_FIRCLPEN_CFG, value: Enabled} -sources: -- {id: SCG.SOSC.outFreq, value: 32.768 kHz, enabled: true} - * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ -/* clang-format on */ - -/******************************************************************************* - * Variables for BOARD_BootClockVLPR configuration - ******************************************************************************/ -const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockVLPR = - { - .divSlow = kSCG_SysClkDivBy8, /* Slow Clock Divider: divided by 8 */ -#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) - .reserved1 = 0, - .reserved2 = 0, - .reserved3 = 0, -#endif - .divCore = kSCG_SysClkDivBy1, /* Core Clock Divider: divided by 1 */ -#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) - .reserved4 = 0, -#endif - .src = kSCG_SysClkSrcSirc, /* Slow IRC is selected as System Clock Source */ -#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) - .reserved5 = 0, -#endif - }; -const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockVLPR = - { - .freq = 0U, /* System Oscillator frequency: 0Hz */ - .enableMode = SCG_SOSC_DISABLE, /* System OSC disabled */ - .monitorMode = kSCG_SysOscMonitorDisable, /* Monitor disabled */ - .div1 = kSCG_AsyncClkDisable, /* System OSC Clock Divider 1: Clock output is disabled */ - .div3 = kSCG_AsyncClkDisable, /* System OSC Clock Divider 3: Clock output is disabled */ - .capLoad = SCG_SYS_OSC_CAP_0P, /* Oscillator capacity load: 0pF */ - .workMode = kSCG_SysOscModeExt, /* Use external clock */ - }; -const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockVLPR = - { - .enableMode = kSCG_SircEnable | kSCG_SircEnableInLowPower,/* Enable SIRC clock, Enable SIRC in low power mode */ - .div1 = kSCG_AsyncClkDisable, /* Slow IRC Clock Divider 1: Clock output is disabled */ - .div3 = kSCG_AsyncClkDisable, /* Slow IRC Clock Divider 3: Clock output is disabled */ - .range = kSCG_SircRangeHigh, /* Slow IRC high range clock (8 MHz) */ - }; -const scg_firc_config_t g_scgFircConfig_BOARD_BootClockVLPR = - { - .enableMode = kSCG_FircEnable | kSCG_FircEnableInLowPower,/* Enable FIRC clock, Enable FIRC in low power mode */ - .div1 = kSCG_AsyncClkDisable, /* Fast IRC Clock Divider 1: Clock output is disabled */ - .div3 = kSCG_AsyncClkDisable, /* Fast IRC Clock Divider 3: Clock output is disabled */ - .range = kSCG_FircRange48M, /* Fast IRC is trimmed to 48MHz */ - .trimConfig = NULL, /* Fast IRC Trim disabled */ - }; -const scg_spll_config_t g_scgSysPllConfig_BOARD_BootClockVLPR = - { - .enableMode = SCG_SPLL_DISABLE, /* System PLL disabled */ - .monitorMode = kSCG_SysPllMonitorDisable, /* Monitor disabled */ - .div1 = kSCG_AsyncClkDisable, /* System PLL Clock Divider 1: Clock output is disabled */ - .div3 = kSCG_AsyncClkDisable, /* System PLL Clock Divider 3: Clock output is disabled */ - .src = kSCG_SysPllSrcSysOsc, /* System PLL clock source is System OSC */ - .prediv = 0, /* Divided by 1 */ - .mult = 0, /* Multiply Factor is 16 */ - }; -/******************************************************************************* - * Code for BOARD_BootClockVLPR configuration - ******************************************************************************/ -void BOARD_BootClockVLPR(void) -{ - /* Init FIRC. */ - CLOCK_CONFIG_FircSafeConfig(&g_scgFircConfig_BOARD_BootClockVLPR); - /* Init SIRC. */ - CLOCK_InitSirc(&g_scgSircConfig_BOARD_BootClockVLPR); - /* Allow SMC all power modes. */ - SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll); - /* Set VLPR power mode. */ - SMC_SetPowerModeVlpr(SMC); - while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateVlpr) - { - } - /* Set SystemCoreClock variable. */ - SystemCoreClock = BOARD_BOOTCLOCKVLPR_CORE_CLOCK; -} diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/clock_config.h b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/clock_config.h deleted file mode 100644 index c01d5e03c..000000000 --- a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/clock_config.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright 2019 ,2021 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/*********************************************************************************************************************** - * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file - * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. - **********************************************************************************************************************/ - -#ifndef _CLOCK_CONFIG_H_ -#define _CLOCK_CONFIG_H_ - -#include "fsl_common.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ -#define BOARD_XTAL0_CLK_HZ 32768U /*!< Board xtal0 frequency in Hz */ - -/******************************************************************************* - ************************ BOARD_InitBootClocks function ************************ - ******************************************************************************/ - -#if defined(__cplusplus) -extern "C" { -#endif /* __cplusplus*/ - -/*! - * @brief This function executes default configuration of clocks. - * - */ -void BOARD_InitBootClocks(void); - -#if defined(__cplusplus) -} -#endif /* __cplusplus*/ - -/******************************************************************************* - ********************** Configuration BOARD_BootClockRUN *********************** - ******************************************************************************/ -/******************************************************************************* - * Definitions for BOARD_BootClockRUN configuration - ******************************************************************************/ -#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */ - -/*! @brief SCG set for BOARD_BootClockRUN configuration. - */ -extern const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockRUN; -/*! @brief System OSC set for BOARD_BootClockRUN configuration. - */ -extern const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockRUN; -/*! @brief SIRC set for BOARD_BootClockRUN configuration. - */ -extern const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockRUN; -/*! @brief FIRC set for BOARD_BootClockRUN configuration. - */ -extern const scg_firc_config_t g_scgFircConfigBOARD_BootClockRUN; -extern const scg_spll_config_t g_scgSysPllConfigBOARD_BootClockRUN; -/*! @brief Low Power FLL set for BOARD_BootClockRUN configuration. - */ - -/******************************************************************************* - * API for BOARD_BootClockRUN configuration - ******************************************************************************/ -#if defined(__cplusplus) -extern "C" { -#endif /* __cplusplus*/ - -/*! - * @brief This function executes configuration of clocks. - * - */ -void BOARD_BootClockRUN(void); - -#if defined(__cplusplus) -} -#endif /* __cplusplus*/ - -/******************************************************************************* - ********************* Configuration BOARD_BootClockHSRUN ********************** - ******************************************************************************/ -/******************************************************************************* - * Definitions for BOARD_BootClockHSRUN configuration - ******************************************************************************/ -#define BOARD_BOOTCLOCKHSRUN_CORE_CLOCK 96000000U /*!< Core clock frequency: 96000000Hz */ - -/*! @brief SCG set for BOARD_BootClockHSRUN configuration. - */ -extern const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockHSRUN; -/*! @brief System OSC set for BOARD_BootClockHSRUN configuration. - */ -extern const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockHSRUN; -/*! @brief SIRC set for BOARD_BootClockHSRUN configuration. - */ -extern const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockHSRUN; -/*! @brief FIRC set for BOARD_BootClockHSRUN configuration. - */ -extern const scg_firc_config_t g_scgFircConfigBOARD_BootClockHSRUN; -extern const scg_spll_config_t g_scgSysPllConfigBOARD_BootClockHSRUN; -/*! @brief Low Power FLL set for BOARD_BootClockHSRUN configuration. - */ - -/******************************************************************************* - * API for BOARD_BootClockHSRUN configuration - ******************************************************************************/ -#if defined(__cplusplus) -extern "C" { -#endif /* __cplusplus*/ - -/*! - * @brief This function executes configuration of clocks. - * - */ -void BOARD_BootClockHSRUN(void); - -#if defined(__cplusplus) -} -#endif /* __cplusplus*/ - -/******************************************************************************* - ********************* Configuration BOARD_BootClockVLPR *********************** - ******************************************************************************/ -/******************************************************************************* - * Definitions for BOARD_BootClockVLPR configuration - ******************************************************************************/ -#define BOARD_BOOTCLOCKVLPR_CORE_CLOCK 8000000U /*!< Core clock frequency: 8000000Hz */ - -/*! @brief SCG set for BOARD_BootClockVLPR configuration. - */ -extern const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockVLPR; -/*! @brief System OSC set for BOARD_BootClockVLPR configuration. - */ -extern const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockVLPR; -/*! @brief SIRC set for BOARD_BootClockVLPR configuration. - */ -extern const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockVLPR; -/*! @brief FIRC set for BOARD_BootClockVLPR configuration. - */ -extern const scg_firc_config_t g_scgFircConfigBOARD_BootClockVLPR; -extern const scg_spll_config_t g_scgSysPllConfigBOARD_BootClockVLPR; -/*! @brief Low Power FLL set for BOARD_BootClockVLPR configuration. - */ - -/******************************************************************************* - * API for BOARD_BootClockVLPR configuration - ******************************************************************************/ -#if defined(__cplusplus) -extern "C" { -#endif /* __cplusplus*/ - -/*! - * @brief This function executes configuration of clocks. - * - */ -void BOARD_BootClockVLPR(void); - -#if defined(__cplusplus) -} -#endif /* __cplusplus*/ - -#endif /* _CLOCK_CONFIG_H_ */ diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.mk b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.mk index 9cf36c500..82456b721 100644 --- a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.mk +++ b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.mk @@ -8,6 +8,9 @@ CFLAGS += -Wno-error=unused-parameter -Wno-error=redundant-decls # All source paths should be relative to the top level. LD_FILE = $(MCU_DIR)/gcc/K32L2B31xxxxA_flash.ld +SRC_C += \ + $(MCU_DIR)/project_template/clock_config.c \ + # For flash-jlink target JLINK_DEVICE = K32L2B31xxxxA diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.c b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.c deleted file mode 100644 index e74000827..000000000 --- a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.c +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright 2019 ,2021 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/*********************************************************************************************************************** - * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file - * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. - **********************************************************************************************************************/ -/* - * How to setup clock using clock driver functions: - * - * 1. CLOCK_SetSimSafeDivs, to make sure core clock, bus clock, flexbus clock - * and flash clock are in allowed range during clock mode switch. - * - * 2. Call CLOCK_Osc0Init to setup OSC clock, if it is used in target mode. - * - * 3. Call CLOCK_SetMcgliteConfig to set MCG_Lite configuration. - * - * 4. Call CLOCK_SetSimConfig to set the clock configuration in SIM. - */ - -/* clang-format off */ -/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* -!!GlobalInfo -product: Clocks v7.0 -processor: K32L2B31xxxxA -package_id: K32L2B31VLH0A -mcu_data: ksdk2_0 -processor_version: 9.0.0 -board: FRDM-K32L2B - * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ -/* clang-format on */ - -#include "fsl_smc.h" -#include "clock_config.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ -#define OSC_CAP0P 0U /*!< Oscillator 0pF capacitor load */ -#define OSC_ER_CLK_DISABLE 0U /*!< Disable external reference clock */ -#define SIM_OSC32KSEL_OSC32KCLK_CLK 0U /*!< OSC32KSEL select: OSC32KCLK clock */ - -/******************************************************************************* - * Variables - ******************************************************************************/ -/* System clock frequency. */ -extern uint32_t SystemCoreClock; - -/******************************************************************************* - ************************ BOARD_InitBootClocks function ************************ - ******************************************************************************/ -void BOARD_InitBootClocks(void) -{ - BOARD_BootClockRUN(); -} - -/******************************************************************************* - ********************** Configuration BOARD_BootClockRUN *********************** - ******************************************************************************/ -/* clang-format off */ -/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* -!!Configuration -name: BOARD_BootClockRUN -called_from_default_init: true -outputs: -- {id: Bus_clock.outFreq, value: 24 MHz} -- {id: Core_clock.outFreq, value: 48 MHz} -- {id: Flash_clock.outFreq, value: 24 MHz} -- {id: LPO_clock.outFreq, value: 1 kHz} -- {id: MCGIRCLK.outFreq, value: 8 MHz} -- {id: MCGPCLK.outFreq, value: 48 MHz} -- {id: System_clock.outFreq, value: 48 MHz} -settings: -- {id: MCGMode, value: HIRC} -- {id: MCG.CLKS.sel, value: MCG.HIRC} -- {id: MCG_C2_OSC_MODE_CFG, value: ModeOscLowPower} -- {id: MCG_C2_RANGE0_CFG, value: Very_high} -- {id: MCG_MC_HIRCEN_CFG, value: Enabled} -- {id: OSC0_CR_ERCLKEN_CFG, value: Enabled} -- {id: OSC_CR_ERCLKEN_CFG, value: Enabled} -- {id: SIM.CLKOUTSEL.sel, value: MCG.MCGPCLK} -- {id: SIM.COPCLKSEL.sel, value: OSC.OSCERCLK} -- {id: SIM.FLEXIOSRCSEL.sel, value: MCG.MCGPCLK} -- {id: SIM.LPUART0SRCSEL.sel, value: MCG.MCGPCLK} -- {id: SIM.LPUART1SRCSEL.sel, value: MCG.MCGPCLK} -- {id: SIM.RTCCLKOUTSEL.sel, value: OSC.OSCERCLK} -- {id: SIM.TPMSRCSEL.sel, value: MCG.MCGPCLK} -- {id: SIM.USBSRCSEL.sel, value: MCG.MCGPCLK} -sources: -- {id: MCG.HIRC.outFreq, value: 48 MHz} -- {id: OSC.OSC.outFreq, value: 32 MHz} - * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ -/* clang-format on */ - -/******************************************************************************* - * 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_OSC32KCLK_CLK, /* OSC32KSEL select: OSC32KCLK clock */ - .clkdiv1 = 0x10000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV4: /2 */ - }; -const osc_config_t oscConfig_BOARD_BootClockRUN = - { - .freq = 0U, /* Oscillator frequency: 0Hz */ - .capLoad = (OSC_CAP0P), /* Oscillator capacity load: 0pF */ - .workMode = kOSC_ModeOscLowPower, /* Oscillator low power */ - .oscerConfig = - { - .enableMode = kOSC_ErClkEnable, /* Enable external reference clock, disable external reference clock in STOP mode */ - } - }; - -/******************************************************************************* - * 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; -} - -/******************************************************************************* - ********************* Configuration BOARD_BootClockVLPR *********************** - ******************************************************************************/ -/* clang-format off */ -/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* -!!Configuration -name: BOARD_BootClockVLPR -outputs: -- {id: Bus_clock.outFreq, value: 1 MHz} -- {id: Core_clock.outFreq, value: 2 MHz} -- {id: Flash_clock.outFreq, value: 1 MHz} -- {id: LPO_clock.outFreq, value: 1 kHz} -- {id: MCGIRCLK.outFreq, value: 2 MHz} -- {id: System_clock.outFreq, value: 2 MHz} -settings: -- {id: MCGMode, value: LIRC2M} -- {id: powerMode, value: VLPR} -- {id: MCG_C2_OSC_MODE_CFG, value: ModeOscLowPower} -- {id: RTCCLKOUTConfig, value: 'yes'} -- {id: SIM.OUTDIV4.scale, value: '2', locked: true} -- {id: SIM.RTCCLKOUTSEL.sel, value: OSC.OSCERCLK} -sources: -- {id: MCG.LIRC.outFreq, value: 2 MHz} -- {id: OSC.OSC.outFreq, value: 32.768 kHz} - * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ -/* clang-format on */ - -/******************************************************************************* - * Variables for BOARD_BootClockVLPR configuration - ******************************************************************************/ -const mcglite_config_t mcgliteConfig_BOARD_BootClockVLPR = - { - .outSrc = kMCGLITE_ClkSrcLirc, /* MCGOUTCLK source is LIRC */ - .irclkEnableMode = kMCGLITE_IrclkEnable, /* MCGIRCLK enabled, MCGIRCLK disabled in STOP mode */ - .ircs = kMCGLITE_Lirc2M, /* Slow internal reference (LIRC) 2 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 = false, /* HIRC source is not enabled */ - }; -const sim_clock_config_t simConfig_BOARD_BootClockVLPR = - { - .er32kSrc = SIM_OSC32KSEL_OSC32KCLK_CLK, /* OSC32KSEL select: OSC32KCLK clock */ - .clkdiv1 = 0x10000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV4: /2 */ - }; -const osc_config_t oscConfig_BOARD_BootClockVLPR = - { - .freq = 0U, /* Oscillator frequency: 0Hz */ - .capLoad = (OSC_CAP0P), /* Oscillator capacity load: 0pF */ - .workMode = kOSC_ModeOscLowPower, /* Oscillator low power */ - .oscerConfig = - { - .enableMode = OSC_ER_CLK_DISABLE, /* Disable external reference clock */ - } - }; - -/******************************************************************************* - * Code for BOARD_BootClockVLPR configuration - ******************************************************************************/ -void BOARD_BootClockVLPR(void) -{ - /* Set the system clock dividers in SIM to safe value. */ - CLOCK_SetSimSafeDivs(); - /* Set MCG to LIRC2M mode. */ - CLOCK_SetMcgliteConfig(&mcgliteConfig_BOARD_BootClockVLPR); - /* Set the clock configuration in SIM module. */ - CLOCK_SetSimConfig(&simConfig_BOARD_BootClockVLPR); - /* Set VLPR power mode. */ - SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll); -#if (defined(FSL_FEATURE_SMC_HAS_LPWUI) && FSL_FEATURE_SMC_HAS_LPWUI) - SMC_SetPowerModeVlpr(SMC, false); -#else - SMC_SetPowerModeVlpr(SMC); -#endif - while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateVlpr) - { - } - /* Set SystemCoreClock variable. */ - SystemCoreClock = BOARD_BOOTCLOCKVLPR_CORE_CLOCK; -} diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.h b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.h deleted file mode 100644 index 37328e7d8..000000000 --- a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2019 ,2021 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/*********************************************************************************************************************** - * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file - * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. - **********************************************************************************************************************/ - -#ifndef _CLOCK_CONFIG_H_ -#define _CLOCK_CONFIG_H_ - -#include "fsl_common.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/******************************************************************************* - ************************ BOARD_InitBootClocks function ************************ - ******************************************************************************/ - -#if defined(__cplusplus) -extern "C" { -#endif /* __cplusplus*/ - -/*! - * @brief This function executes default configuration of clocks. - * - */ -void BOARD_InitBootClocks(void); - -#if defined(__cplusplus) -} -#endif /* __cplusplus*/ - -/******************************************************************************* - ********************** Configuration BOARD_BootClockRUN *********************** - ******************************************************************************/ -/******************************************************************************* - * Definitions for BOARD_BootClockRUN configuration - ******************************************************************************/ -#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */ - -/*! @brief MCG lite set for BOARD_BootClockRUN configuration. - */ -extern const mcglite_config_t mcgliteConfig_BOARD_BootClockRUN; -/*! @brief SIM module set for BOARD_BootClockRUN configuration. - */ -extern const sim_clock_config_t simConfig_BOARD_BootClockRUN; -/*! @brief OSC set for BOARD_BootClockRUN configuration. - */ -extern const osc_config_t oscConfig_BOARD_BootClockRUN; - -/******************************************************************************* - * API for BOARD_BootClockRUN configuration - ******************************************************************************/ -#if defined(__cplusplus) -extern "C" { -#endif /* __cplusplus*/ - -/*! - * @brief This function executes configuration of clocks. - * - */ -void BOARD_BootClockRUN(void); - -#if defined(__cplusplus) -} -#endif /* __cplusplus*/ - -/******************************************************************************* - ********************* Configuration BOARD_BootClockVLPR *********************** - ******************************************************************************/ -/******************************************************************************* - * Definitions for BOARD_BootClockVLPR configuration - ******************************************************************************/ -#define BOARD_BOOTCLOCKVLPR_CORE_CLOCK 2000000U /*!< Core clock frequency: 2000000Hz */ - -/*! @brief MCG lite set for BOARD_BootClockVLPR configuration. - */ -extern const mcglite_config_t mcgliteConfig_BOARD_BootClockVLPR; -/*! @brief SIM module set for BOARD_BootClockVLPR configuration. - */ -extern const sim_clock_config_t simConfig_BOARD_BootClockVLPR; -/*! @brief OSC set for BOARD_BootClockVLPR configuration. - */ -extern const osc_config_t oscConfig_BOARD_BootClockVLPR; - -/******************************************************************************* - * API for BOARD_BootClockVLPR configuration - ******************************************************************************/ -#if defined(__cplusplus) -extern "C" { -#endif /* __cplusplus*/ - -/*! - * @brief This function executes configuration of clocks. - * - */ -void BOARD_BootClockVLPR(void); - -#if defined(__cplusplus) -} -#endif /* __cplusplus*/ - -#endif /* _CLOCK_CONFIG_H_ */ diff --git a/hw/bsp/nrf/boards/pca10095/board.cmake b/hw/bsp/nrf/boards/pca10095/board.cmake index 0fbc1d31f..ca5399a3a 100644 --- a/hw/bsp/nrf/boards/pca10095/board.cmake +++ b/hw/bsp/nrf/boards/pca10095/board.cmake @@ -1,9 +1,6 @@ set(MCU_VARIANT nrf5340_application) set(LD_FILE_GNU ${NRFX_DIR}/mdk/nrf5340_xxaa_application.ld) -# enable max3421 host driver for this board -set(MAX3421_HOST 1) - function(update_board TARGET) target_sources(${TARGET} PRIVATE ${NRFX_DIR}/drivers/src/nrfx_usbreg.c diff --git a/hw/bsp/nrf/boards/pca10095/board.h b/hw/bsp/nrf/boards/pca10095/board.h index 7437dad48..ad3379bf6 100644 --- a/hw/bsp/nrf/boards/pca10095/board.h +++ b/hw/bsp/nrf/boards/pca10095/board.h @@ -42,8 +42,8 @@ #define BUTTON_STATE_ACTIVE 0 // UART -#define UART_RX_PIN 22 -#define UART_TX_PIN 20 +#define UART_RX_PIN 32 +#define UART_TX_PIN 33 // SPI for USB host shield #define MAX3421_SCK_PIN _PINNUM(1, 15) diff --git a/hw/bsp/nrf/boards/pca10095/board.mk b/hw/bsp/nrf/boards/pca10095/board.mk index 20580d619..9c4edbafc 100644 --- a/hw/bsp/nrf/boards/pca10095/board.mk +++ b/hw/bsp/nrf/boards/pca10095/board.mk @@ -2,9 +2,6 @@ CPU_CORE = cortex-m33 MCU_VARIANT = nrf5340_application CFLAGS += -DNRF5340_XXAA -DNRF5340_XXAA_APPLICATION -# enable max3421 host driver for this board -MAX3421_HOST = 1 - LD_FILE = hw/mcu/nordic/nrfx/mdk/nrf5340_xxaa_application.ld SRC_C += hw/mcu/nordic/nrfx/drivers/src/nrfx_usbreg.c diff --git a/hw/bsp/nrf/family.c b/hw/bsp/nrf/family.c index 55119ef02..7a970f52e 100644 --- a/hw/bsp/nrf/family.c +++ b/hw/bsp/nrf/family.c @@ -76,7 +76,6 @@ enum { #define LFCLK_SRC_RC CLOCK_LFCLKSRC_SRC_LFRC #define VBUSDETECT_Msk USBREG_USBREGSTATUS_VBUSDETECT_Msk #define OUTPUTRDY_Msk USBREG_USBREGSTATUS_OUTPUTRDY_Msk - #define GPIOTE_IRQn GPIOTE1_IRQn #else #define LFCLK_SRC_RC CLOCK_LFCLKSRC_SRC_RC #define VBUSDETECT_Msk POWER_USBREGSTATUS_VBUSDETECT_Msk diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index c145d86a6..2589dcd2c 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -203,7 +203,7 @@ uint8_t rdwr10_validate_cmd(msc_cbw_t const* cbw) //--------------------------------------------------------------------+ // Debug //--------------------------------------------------------------------+ -#if CFG_TUSB_DEBUG >= CFG_TUD_MSC_LOG_LEVEL +#if CFG_TUSB_DEBUG >= 2 TU_ATTR_UNUSED tu_static tu_lookup_entry_t const _msc_scsi_cmd_lookup[] = { diff --git a/src/class/video/video.h b/src/class/video/video.h index abf1e34b9..6319c6536 100644 --- a/src/class/video/video.h +++ b/src/class/video/video.h @@ -368,8 +368,6 @@ typedef struct TU_ATTR_PACKED { uint8_t bCopyProtect; } tusb_desc_video_format_uncompressed_t; -TU_VERIFY_STATIC(sizeof(tusb_desc_video_format_uncompressed_t) == 27, "size is not correct"); - // Uncompressed payload specs: 3.1.2 frame descriptor #define tusb_desc_video_frame_uncompressed_nint_t(_nint) \ struct TU_ATTR_PACKED { \ @@ -383,7 +381,7 @@ TU_VERIFY_STATIC(sizeof(tusb_desc_video_format_uncompressed_t) == 27, "size is n uint32_t dwMinBitRate; \ uint32_t dwMaxBitRate; \ uint32_t dwMaxVideoFrameBufferSize; /* deprecated in 1.5 */ \ - uint32_t dwDefaultFrameInterval; /* 100ns unit */\ + uint32_t dwDefaultFrameInterval; \ uint8_t bFrameIntervalType; \ uint32_t dwFrameInterval[_nint]; \ } @@ -415,8 +413,6 @@ typedef struct TU_ATTR_PACKED { uint8_t bCopyProtect; } tusb_desc_video_format_mjpeg_t; -TU_VERIFY_STATIC(sizeof(tusb_desc_video_format_mjpeg_t) == 11, "size is not correct"); - // MJPEG payload specs: 3.1.2 frame descriptor (same as uncompressed) typedef tusb_desc_video_frame_uncompressed_t tusb_desc_video_frame_mjpeg_t; typedef tusb_desc_video_frame_uncompressed_1int_t tusb_desc_video_frame_mjpeg_1int_t; diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index c33dfa0b0..1affd615e 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -559,7 +559,6 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * uint_fast8_t num_intervals = frm->uncompressed.bFrameIntervalType; if (num_intervals) { interval = 0; - interval_ms = 0; } else { interval = frm->uncompressed.dwFrameInterval[2]; interval_ms = interval / 10000; diff --git a/src/common/tusb_debug.h b/src/common/tusb_debug.h index 2e9f1d9cd..0f4dc93f3 100644 --- a/src/common/tusb_debug.h +++ b/src/common/tusb_debug.h @@ -60,7 +60,6 @@ void tu_print_mem(void const *buf, uint32_t count, uint8_t indent); static inline void tu_print_buf(uint8_t const* buf, uint32_t bufsize) { for(uint32_t i=0; i= 2 diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index 76696396b..d6c3db4ce 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -224,7 +224,6 @@ 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; - default: break; } } diff --git a/src/device/usbd.c b/src/device/usbd.c index be85d7769..5c94ebcc5 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -500,6 +500,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) case DCD_EVENT_SETUP_RECEIVED: TU_LOG_BUF(CFG_TUD_LOG_LEVEL, &event.setup_received, 8); + TU_LOG_USBD("\r\n"); // Mark as connected after receiving 1st setup packet. // But it is easier to set it every time instead of wasting time to check then set diff --git a/src/host/usbh.c b/src/host/usbh.c index f56290a0c..dfe6ddb42 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -343,12 +343,12 @@ bool tuh_init(uint8_t controller_id) { if ( tuh_inited() ) return true; TU_LOG_USBH("USBH init on controller %u\r\n", controller_id); - TU_LOG_INT_USBH(sizeof(usbh_device_t)); - TU_LOG_INT_USBH(sizeof(hcd_event_t)); - TU_LOG_INT_USBH(sizeof(_ctrl_xfer)); - TU_LOG_INT_USBH(sizeof(tuh_xfer_t)); - TU_LOG_INT_USBH(sizeof(tu_fifo_t)); - TU_LOG_INT_USBH(sizeof(tu_edpt_stream_t)); + TU_LOG_INT(CFG_TUH_LOG_LEVEL, sizeof(usbh_device_t)); + TU_LOG_INT(CFG_TUH_LOG_LEVEL, sizeof(hcd_event_t)); + TU_LOG_INT(CFG_TUH_LOG_LEVEL, sizeof(_ctrl_xfer)); + TU_LOG_INT(CFG_TUH_LOG_LEVEL, sizeof(tuh_xfer_t)); + TU_LOG_INT(CFG_TUH_LOG_LEVEL, sizeof(tu_fifo_t)); + TU_LOG_INT(CFG_TUH_LOG_LEVEL, sizeof(tu_edpt_stream_t)); // Event queue _usbh_q = osal_queue_create( &_usbh_qdef ); @@ -588,7 +588,8 @@ bool tuh_control_xfer (tuh_xfer_t* xfer) { TU_LOG_USBH("[%u:%u] %s: ", rhport, daddr, (xfer->setup->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && xfer->setup->bRequest <= TUSB_REQ_SYNCH_FRAME) ? tu_str_std_request[xfer->setup->bRequest] : "Class Request"); - TU_LOG_BUF_USBH(xfer->setup, 8); + TU_LOG_BUF(CFG_TUH_LOG_LEVEL, xfer->setup, 8); + TU_LOG_USBH("\r\n"); if (xfer->complete_cb) { TU_ASSERT( hcd_setup_send(rhport, daddr, (uint8_t const*) &_ctrl_xfer.request) ); @@ -659,8 +660,9 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result tusb_control_request_t const * request = &_ctrl_xfer.request; if (XFER_RESULT_SUCCESS != result) { - TU_LOG_USBH("[%u:%u] Control %s, xferred_bytes = %lu\r\n", rhport, dev_addr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED", xferred_bytes); - TU_LOG_BUF_USBH(request, 8); + TU_LOG1("[%u:%u] Control %s, xferred_bytes = %lu\r\n", rhport, dev_addr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED", xferred_bytes); + TU_LOG1_BUF(request, 8); + TU_LOG1("\r\n"); // terminate transfer if any stage failed _xfer_complete(dev_addr, result); @@ -678,7 +680,7 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result case CONTROL_STAGE_DATA: if (request->wLength) { TU_LOG_USBH("[%u:%u] Control data:\r\n", rhport, dev_addr); - TU_LOG_MEM_USBH(_ctrl_xfer.buffer, xferred_bytes, 2); + TU_LOG_MEM(CFG_TUH_LOG_LEVEL, _ctrl_xfer.buffer, xferred_bytes, 2); } _ctrl_xfer.actual_len = (uint16_t) xferred_bytes; diff --git a/src/host/usbh_pvt.h b/src/host/usbh_pvt.h index 4ed2a72b5..4a97a1c18 100644 --- a/src/host/usbh_pvt.h +++ b/src/host/usbh_pvt.h @@ -35,11 +35,7 @@ extern "C" { #endif -#define TU_LOG_USBH(...) TU_LOG(CFG_TUH_LOG_LEVEL, __VA_ARGS__) -#define TU_LOG_MEM_USBH(...) TU_LOG_MEM(CFG_TUH_LOG_LEVEL, __VA_ARGS__) -#define TU_LOG_BUF_USBH(...) TU_LOG_BUF(CFG_TUH_LOG_LEVEL, __VA_ARGS__) -#define TU_LOG_INT_USBH(...) TU_LOG_INT(CFG_TUH_LOG_LEVEL, __VA_ARGS__) -#define TU_LOG_HEX_USBH(...) TU_LOG_HEX(CFG_TUH_LOG_LEVEL, __VA_ARGS__) +#define TU_LOG_USBH(...) TU_LOG(CFG_TUH_LOG_LEVEL, __VA_ARGS__) enum { USBH_EPSIZE_BULK_MAX = (TUH_OPT_HIGH_SPEED ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS) diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index 841cda752..4e702aed4 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -653,11 +653,7 @@ void dcd_int_handler(uint8_t rhport) if (NRF_USBD->EPOUTEN & USBD_EPOUTEN_ISOOUT_Msk) { iso_enabled = true; - // Transfer from endpoint to RAM only if data is not corrupted - if ((int_status & USBD_INTEN_USBEVENT_Msk) == 0 || - (NRF_USBD->EVENTCAUSE & USBD_EVENTCAUSE_ISOOUTCRC_Msk) == 0) { - xact_out_dma(EP_ISO_NUM); - } + xact_out_dma(EP_ISO_NUM); } // ISOIN: Notify client that data was transferred @@ -687,7 +683,7 @@ void dcd_int_handler(uint8_t rhport) { TU_LOG(2, "EVENTCAUSE = 0x%04lX\r\n", NRF_USBD->EVENTCAUSE); - enum { EVT_CAUSE_MASK = USBD_EVENTCAUSE_SUSPEND_Msk | USBD_EVENTCAUSE_RESUME_Msk | USBD_EVENTCAUSE_USBWUALLOWED_Msk | USBD_EVENTCAUSE_ISOOUTCRC_Msk }; + enum { EVT_CAUSE_MASK = USBD_EVENTCAUSE_SUSPEND_Msk | USBD_EVENTCAUSE_RESUME_Msk | USBD_EVENTCAUSE_USBWUALLOWED_Msk }; uint32_t const evt_cause = NRF_USBD->EVENTCAUSE & EVT_CAUSE_MASK; NRF_USBD->EVENTCAUSE = evt_cause; // clear interrupt diff --git a/src/portable/ohci/ohci.h b/src/portable/ohci/ohci.h index 94bad5df7..4feefd771 100644 --- a/src/portable/ohci/ohci.h +++ b/src/portable/ohci/ohci.h @@ -83,7 +83,7 @@ typedef struct TU_ATTR_ALIGNED(16) volatile uint32_t condition_code : 4; // Word 1 - uint8_t* volatile current_buffer_pointer; + volatile uint8_t* current_buffer_pointer; // Word 2 : next TD volatile uint32_t next; From a1bfde83fbc4c7e62801f74377d0fe4543570307 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 23 Feb 2024 13:18:52 +0700 Subject: [PATCH 121/454] adding frdm k64f, board test run well with led, button and uart --- .idea/cmake.xml | 2 +- hw/bsp/kinetis_k/boards/frdm_k64f/board.cmake | 16 + hw/bsp/kinetis_k/boards/frdm_k64f/board.h | 45 + hw/bsp/kinetis_k/boards/frdm_k64f/board.mk | 19 + .../boards/frdm_k64f/board/clock_config.c | 324 +++++++ .../boards/frdm_k64f/board/clock_config.h | 104 ++ .../boards/frdm_k64f/board/pin_mux.c | 852 ++++++++++++++++ .../boards/frdm_k64f/board/pin_mux.h | 645 +++++++++++++ .../kinetis_k/boards/frdm_k64f/frdm_k64f.mex | 913 ++++++++++++++++++ hw/bsp/kinetis_k/family.c | 52 +- hw/bsp/kinetis_k/family.cmake | 2 +- 11 files changed, 2946 insertions(+), 28 deletions(-) create mode 100644 hw/bsp/kinetis_k/boards/frdm_k64f/board.cmake create mode 100644 hw/bsp/kinetis_k/boards/frdm_k64f/board.h create mode 100644 hw/bsp/kinetis_k/boards/frdm_k64f/board.mk create mode 100644 hw/bsp/kinetis_k/boards/frdm_k64f/board/clock_config.c create mode 100644 hw/bsp/kinetis_k/boards/frdm_k64f/board/clock_config.h create mode 100644 hw/bsp/kinetis_k/boards/frdm_k64f/board/pin_mux.c create mode 100644 hw/bsp/kinetis_k/boards/frdm_k64f/board/pin_mux.h create mode 100644 hw/bsp/kinetis_k/boards/frdm_k64f/frdm_k64f.mex diff --git a/.idea/cmake.xml b/.idea/cmake.xml index baf837af6..dbb34aaab 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -59,7 +59,7 @@ - + diff --git a/hw/bsp/kinetis_k/boards/frdm_k64f/board.cmake b/hw/bsp/kinetis_k/boards/frdm_k64f/board.cmake new file mode 100644 index 000000000..8ded9c1d5 --- /dev/null +++ b/hw/bsp/kinetis_k/boards/frdm_k64f/board.cmake @@ -0,0 +1,16 @@ +set(MCU_VARIANT MK64F12) + +set(JLINK_DEVICE MK64FN1M0xxx12) +set(PYOCD_TARGET k64f) + +set(LD_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/MK64FN1M0xxx12_flash.ld) + +function(update_board TARGET) + target_sources(${TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/board/pin_mux.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/board/clock_config.c + ) + target_compile_definitions(${TARGET} PUBLIC + CPU_MK64FN1M0VMD12 + ) +endfunction() diff --git a/hw/bsp/kinetis_k/boards/frdm_k64f/board.h b/hw/bsp/kinetis_k/boards/frdm_k64f/board.h new file mode 100644 index 000000000..ae8c66182 --- /dev/null +++ b/hw/bsp/kinetis_k/boards/frdm_k64f/board.h @@ -0,0 +1,45 @@ +/* + * 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. + */ + +#ifndef BOARD_H +#define BOARD_H + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM DECLARATION +//--------------------------------------------------------------------+ +// LED +#define LED_PORT BOARD_LED_RED_GPIO +#define LED_PIN BOARD_LED_RED_GPIO_PIN +#define LED_STATE_ON 0 + +// Button +#define BUTTON_PORT BOARD_SW2_GPIO +#define BUTTON_PIN BOARD_SW2_GPIO_PIN +#define BUTTON_STATE_ACTIVE 0 + +// UART +#define UART_DEV UART0 +#define UART_CLOCK CLOCK_GetFreq(UART0_CLK_SRC) + +#endif diff --git a/hw/bsp/kinetis_k/boards/frdm_k64f/board.mk b/hw/bsp/kinetis_k/boards/frdm_k64f/board.mk new file mode 100644 index 000000000..101fd49aa --- /dev/null +++ b/hw/bsp/kinetis_k/boards/frdm_k64f/board.mk @@ -0,0 +1,19 @@ +MCU_VARIANT = MK64F12 + +CFLAGS += \ + -DCPU_MK64FN1M0VMD12 \ + +# mcu driver cause following warnings +CFLAGS += -Wno-error=unused-parameter -Wno-error=format -Wno-error=redundant-decls + +SRC_C += \ + $(BOARD_PATH)/board/clock_config.c \ + $(BOARD_PATH)/board/pin_mux.c \ + +LD_FILE = ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/MK64FN1M0xxx12_flash.ld + +# For flash-jlink target +JLINK_DEVICE = MK64FN1M0xxx12 + +# For flash-pyocd target +PYOCD_TARGET = k64f diff --git a/hw/bsp/kinetis_k/boards/frdm_k64f/board/clock_config.c b/hw/bsp/kinetis_k/boards/frdm_k64f/board/clock_config.c new file mode 100644 index 000000000..0933c6da9 --- /dev/null +++ b/hw/bsp/kinetis_k/boards/frdm_k64f/board/clock_config.c @@ -0,0 +1,324 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ +/* + * How to setup clock using clock driver functions: + * + * 1. CLOCK_SetSimSafeDivs, to make sure core clock, bus clock, flexbus clock + * and flash clock are in allowed range during clock mode switch. + * + * 2. Call CLOCK_Osc0Init to setup OSC clock, if it is used in target mode. + * + * 3. Set MCG configuration, MCG includes three parts: FLL clock, PLL clock and + * internal reference clock(MCGIRCLK). Follow the steps to setup: + * + * 1). Call CLOCK_BootToXxxMode to set MCG to target mode. + * + * 2). If target mode is FBI/BLPI/PBI mode, the MCGIRCLK has been configured + * correctly. For other modes, need to call CLOCK_SetInternalRefClkConfig + * explicitly to setup MCGIRCLK. + * + * 3). Don't need to configure FLL explicitly, because if target mode is FLL + * mode, then FLL has been configured by the function CLOCK_BootToXxxMode, + * if the target mode is not FLL mode, the FLL is disabled. + * + * 4). If target mode is PEE/PBE/PEI/PBI mode, then the related PLL has been + * setup by CLOCK_BootToXxxMode. In FBE/FBI/FEE/FBE mode, the PLL could + * be enabled independently, call CLOCK_EnablePll0 explicitly in this case. + * + * 4. Call CLOCK_SetSimConfig to set the clock configuration in SIM. + */ + +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Clocks v12.0 +processor: MK64FN1M0xxx12 +package_id: MK64FN1M0VLL12 +mcu_data: ksdk2_0 +processor_version: 14.0.0 +board: FRDM-K64F + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +#include "fsl_smc.h" +#include "clock_config.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define MCG_IRCLK_DISABLE 0U /*!< MCGIRCLK disabled */ +#define MCG_PLL_DISABLE 0U /*!< MCGPLLCLK disabled */ +#define OSC_CAP0P 0U /*!< Oscillator 0pF capacitor load */ +#define OSC_ER_CLK_DISABLE 0U /*!< Disable external reference clock */ +#define SIM_CLKOUT_SEL_FLEXBUS_CLK 0U /*!< CLKOUT pin clock select: FlexBus clock */ +#define SIM_ENET_1588T_CLK_SEL_OSCERCLK_CLK 2U /*!< SDHC clock select: OSCERCLK clock */ +#define SIM_ENET_RMII_CLK_SEL_EXTAL_CLK 0U /*!< SDHC clock select: Core/system clock */ +#define SIM_OSC32KSEL_RTC32KCLK_CLK 2U /*!< OSC32KSEL select: RTC32KCLK clock (32.768kHz) */ +#define SIM_PLLFLLSEL_IRC48MCLK_CLK 3U /*!< PLLFLL select: IRC48MCLK clock */ +#define SIM_PLLFLLSEL_MCGPLLCLK_CLK 1U /*!< PLLFLL select: MCGPLLCLK clock */ +#define SIM_SDHC_CLK_SEL_OSCERCLK_CLK 2U /*!< SDHC clock select: OSCERCLK clock */ +#define SIM_TRACE_CLK_SEL_CORE_SYSTEM_CLK 1U /*!< Trace clock select: Core/system clock */ +#define SIM_USB_CLK_120000000HZ 120000000U /*!< Input SIM frequency for USB: 120000000Hz */ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Code + ******************************************************************************/ +/*FUNCTION********************************************************************** + * + * Function Name : CLOCK_CONFIG_SetFllExtRefDiv + * Description : Configure FLL external reference divider (FRDIV). + * Param frdiv : The value to set FRDIV. + * + *END**************************************************************************/ +static void CLOCK_CONFIG_SetFllExtRefDiv(uint8_t frdiv) +{ + MCG->C1 = ((MCG->C1 & ~MCG_C1_FRDIV_MASK) | MCG_C1_FRDIV(frdiv)); +} + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ +void BOARD_InitBootClocks(void) +{ +} + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockRUN +outputs: +- {id: Bus_clock.outFreq, value: 60 MHz} +- {id: CLKOUT.outFreq, value: 40 MHz} +- {id: Core_clock.outFreq, value: 120 MHz, locked: true, accuracy: '0.001'} +- {id: ENET1588TSCLK.outFreq, value: 50 MHz} +- {id: Flash_clock.outFreq, value: 24 MHz} +- {id: FlexBus_clock.outFreq, value: 40 MHz} +- {id: LPO_clock.outFreq, value: 1 kHz} +- {id: MCGFFCLK.outFreq, value: 1.5625 MHz} +- {id: MCGIRCLK.outFreq, value: 2 MHz} +- {id: OSCERCLK.outFreq, value: 50 MHz} +- {id: PLLFLLCLK.outFreq, value: 120 MHz} +- {id: RMIICLK.outFreq, value: 50 MHz} +- {id: SDHCCLK.outFreq, value: 50 MHz} +- {id: System_clock.outFreq, value: 120 MHz} +- {id: TRACECLKIN.outFreq, value: 120 MHz} +- {id: USB48MCLK.outFreq, value: 48 MHz} +settings: +- {id: MCGMode, value: PEE} +- {id: CLKOUTConfig, value: 'yes'} +- {id: ENETTimeSrcConfig, value: 'yes'} +- {id: MCG.FRDIV.scale, value: '32'} +- {id: MCG.IRCS.sel, value: MCG.FCRDIV} +- {id: MCG.IREFS.sel, value: MCG.FRDIV} +- {id: MCG.PLLS.sel, value: MCG.PLL} +- {id: MCG.PRDIV.scale, value: '15'} +- {id: MCG.VDIV.scale, value: '36'} +- {id: MCG_C1_IRCLKEN_CFG, value: Enabled} +- {id: MCG_C2_RANGE0_CFG, value: Very_high} +- {id: MCG_C2_RANGE0_FRDIV_CFG, value: Very_high} +- {id: OSC_CR_ERCLKEN_CFG, value: Enabled} +- {id: RMIISrcConfig, value: 'yes'} +- {id: RTCCLKOUTConfig, value: 'yes'} +- {id: RTC_CR_OSCE_CFG, value: Enabled} +- {id: RTC_CR_OSC_CAP_LOAD_CFG, value: SC10PF} +- {id: SDHCClkConfig, value: 'yes'} +- {id: SIM.OSC32KSEL.sel, value: RTC.RTC32KCLK} +- {id: SIM.OUTDIV2.scale, value: '2'} +- {id: SIM.OUTDIV3.scale, value: '3'} +- {id: SIM.OUTDIV4.scale, value: '5'} +- {id: SIM.PLLFLLSEL.sel, value: MCG.MCGPLLCLK} +- {id: SIM.RTCCLKOUTSEL.sel, value: RTC.RTC32KCLK} +- {id: SIM.SDHCSRCSEL.sel, value: OSC.OSCERCLK} +- {id: SIM.TIMESRCSEL.sel, value: OSC.OSCERCLK} +- {id: SIM.USBDIV.scale, value: '5'} +- {id: SIM.USBFRAC.scale, value: '2'} +- {id: SIM.USBSRCSEL.sel, value: SIM.USBDIV} +- {id: TraceClkConfig, value: 'yes'} +- {id: USBClkConfig, value: 'yes'} +sources: +- {id: OSC.OSC.outFreq, value: 50 MHz, enabled: true} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockRUN configuration + ******************************************************************************/ +const mcg_config_t mcgConfig_BOARD_BootClockRUN = + { + .mcgMode = kMCG_ModePEE, /* PEE - PLL Engaged External */ + .irclkEnableMode = kMCG_IrclkEnable, /* MCGIRCLK enabled, MCGIRCLK disabled in STOP mode */ + .ircs = kMCG_IrcFast, /* Fast internal reference clock selected */ + .fcrdiv = 0x1U, /* Fast IRC divider: divided by 2 */ + .frdiv = 0x0U, /* FLL reference clock divider: divided by 32 */ + .drs = kMCG_DrsLow, /* Low frequency range */ + .dmx32 = kMCG_Dmx32Default, /* DCO has a default range of 25% */ + .oscsel = kMCG_OscselOsc, /* Selects System Oscillator (OSCCLK) */ + .pll0Config = + { + .enableMode = MCG_PLL_DISABLE, /* MCGPLLCLK disabled */ + .prdiv = 0xeU, /* PLL Reference divider: divided by 15 */ + .vdiv = 0xcU, /* VCO divider: multiplied by 36 */ + }, + }; +const sim_clock_config_t simConfig_BOARD_BootClockRUN = + { + .pllFllSel = SIM_PLLFLLSEL_MCGPLLCLK_CLK, /* PLLFLL select: MCGPLLCLK clock */ + .er32kSrc = SIM_OSC32KSEL_RTC32KCLK_CLK, /* OSC32KSEL select: RTC32KCLK clock (32.768kHz) */ + .clkdiv1 = 0x1240000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV2: /2, OUTDIV3: /3, OUTDIV4: /5 */ + }; +const osc_config_t oscConfig_BOARD_BootClockRUN = + { + .freq = 50000000U, /* Oscillator frequency: 50000000Hz */ + .capLoad = (OSC_CAP0P), /* Oscillator capacity load: 0pF */ + .workMode = kOSC_ModeExt, /* Use external clock */ + .oscerConfig = + { + .enableMode = kOSC_ErClkEnable, /* Enable external reference clock, disable external reference clock in STOP mode */ + } + }; + +/******************************************************************************* + * Code for BOARD_BootClockRUN configuration + ******************************************************************************/ +void BOARD_BootClockRUN(void) +{ + /* Set the system clock dividers in SIM to safe value. */ + CLOCK_SetSimSafeDivs(); + /* Initializes OSC0 according to board configuration. */ + CLOCK_InitOsc0(&oscConfig_BOARD_BootClockRUN); + CLOCK_SetXtal0Freq(oscConfig_BOARD_BootClockRUN.freq); + /* Configure the Internal Reference clock (MCGIRCLK). */ + CLOCK_SetInternalRefClkConfig(mcgConfig_BOARD_BootClockRUN.irclkEnableMode, + mcgConfig_BOARD_BootClockRUN.ircs, + mcgConfig_BOARD_BootClockRUN.fcrdiv); + /* Configure FLL external reference divider (FRDIV). */ + CLOCK_CONFIG_SetFllExtRefDiv(mcgConfig_BOARD_BootClockRUN.frdiv); + /* Set MCG to PEE mode. */ + CLOCK_BootToPeeMode(mcgConfig_BOARD_BootClockRUN.oscsel, + kMCG_PllClkSelPll0, + &mcgConfig_BOARD_BootClockRUN.pll0Config); + /* Set the clock configuration in SIM module. */ + CLOCK_SetSimConfig(&simConfig_BOARD_BootClockRUN); + /* Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; + /* Enable USB FS clock. */ + CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcPll0, SIM_USB_CLK_120000000HZ); + /* Set enet timestamp clock source. */ + CLOCK_SetEnetTime0Clock(SIM_ENET_1588T_CLK_SEL_OSCERCLK_CLK); + /* Set RMII clock source. */ + CLOCK_SetRmii0Clock(SIM_ENET_RMII_CLK_SEL_EXTAL_CLK); + /* Set SDHC clock source. */ + CLOCK_SetSdhc0Clock(SIM_SDHC_CLK_SEL_OSCERCLK_CLK); + /* Set CLKOUT source. */ + CLOCK_SetClkOutClock(SIM_CLKOUT_SEL_FLEXBUS_CLK); + /* Set debug trace clock source. */ + CLOCK_SetTraceClock(SIM_TRACE_CLK_SEL_CORE_SYSTEM_CLK); +} + +/******************************************************************************* + ********************* Configuration BOARD_BootClockVLPR *********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockVLPR +outputs: +- {id: Bus_clock.outFreq, value: 4 MHz} +- {id: Core_clock.outFreq, value: 4 MHz, locked: true, accuracy: '0.001'} +- {id: Flash_clock.outFreq, value: 800 kHz} +- {id: FlexBus_clock.outFreq, value: 4 MHz} +- {id: LPO_clock.outFreq, value: 1 kHz} +- {id: System_clock.outFreq, value: 4 MHz} +settings: +- {id: MCGMode, value: BLPI} +- {id: powerMode, value: VLPR} +- {id: MCG.CLKS.sel, value: MCG.IRCS} +- {id: MCG.FCRDIV.scale, value: '1'} +- {id: MCG.FRDIV.scale, value: '32'} +- {id: MCG.IRCS.sel, value: MCG.FCRDIV} +- {id: MCG_C2_RANGE0_CFG, value: Very_high} +- {id: MCG_C2_RANGE0_FRDIV_CFG, value: Very_high} +- {id: RTC_CR_OSCE_CFG, value: Enabled} +- {id: RTC_CR_OSC_CAP_LOAD_CFG, value: SC10PF} +- {id: SIM.OSC32KSEL.sel, value: RTC.RTC32KCLK} +- {id: SIM.OUTDIV3.scale, value: '1'} +- {id: SIM.OUTDIV4.scale, value: '5'} +- {id: SIM.PLLFLLSEL.sel, value: IRC48M.IRC48MCLK} +- {id: SIM.RTCCLKOUTSEL.sel, value: RTC.RTC32KCLK} +sources: +- {id: OSC.OSC.outFreq, value: 50 MHz} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockVLPR configuration + ******************************************************************************/ +const mcg_config_t mcgConfig_BOARD_BootClockVLPR = + { + .mcgMode = kMCG_ModeBLPI, /* BLPI - Bypassed Low Power Internal */ + .irclkEnableMode = MCG_IRCLK_DISABLE, /* MCGIRCLK disabled */ + .ircs = kMCG_IrcFast, /* Fast internal reference clock selected */ + .fcrdiv = 0x0U, /* Fast IRC divider: divided by 1 */ + .frdiv = 0x0U, /* FLL reference clock divider: divided by 32 */ + .drs = kMCG_DrsLow, /* Low frequency range */ + .dmx32 = kMCG_Dmx32Default, /* DCO has a default range of 25% */ + .oscsel = kMCG_OscselOsc, /* Selects System Oscillator (OSCCLK) */ + .pll0Config = + { + .enableMode = MCG_PLL_DISABLE, /* MCGPLLCLK disabled */ + .prdiv = 0x0U, /* PLL Reference divider: divided by 1 */ + .vdiv = 0x0U, /* VCO divider: multiplied by 24 */ + }, + }; +const sim_clock_config_t simConfig_BOARD_BootClockVLPR = + { + .pllFllSel = SIM_PLLFLLSEL_IRC48MCLK_CLK, /* PLLFLL select: IRC48MCLK clock */ + .er32kSrc = SIM_OSC32KSEL_RTC32KCLK_CLK, /* OSC32KSEL select: RTC32KCLK clock (32.768kHz) */ + .clkdiv1 = 0x40000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV2: /1, OUTDIV3: /1, OUTDIV4: /5 */ + }; +const osc_config_t oscConfig_BOARD_BootClockVLPR = + { + .freq = 0U, /* Oscillator frequency: 0Hz */ + .capLoad = (OSC_CAP0P), /* Oscillator capacity load: 0pF */ + .workMode = kOSC_ModeExt, /* Use external clock */ + .oscerConfig = + { + .enableMode = OSC_ER_CLK_DISABLE, /* Disable external reference clock */ + } + }; + +/******************************************************************************* + * Code for BOARD_BootClockVLPR configuration + ******************************************************************************/ +void BOARD_BootClockVLPR(void) +{ + /* Set the system clock dividers in SIM to safe value. */ + CLOCK_SetSimSafeDivs(); + /* Set MCG to BLPI mode. */ + CLOCK_BootToBlpiMode(mcgConfig_BOARD_BootClockVLPR.fcrdiv, + mcgConfig_BOARD_BootClockVLPR.ircs, + mcgConfig_BOARD_BootClockVLPR.irclkEnableMode); + /* Set the clock configuration in SIM module. */ + CLOCK_SetSimConfig(&simConfig_BOARD_BootClockVLPR); + /* Set VLPR power mode. */ + SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll); +#if (defined(FSL_FEATURE_SMC_HAS_LPWUI) && FSL_FEATURE_SMC_HAS_LPWUI) + SMC_SetPowerModeVlpr(SMC, false); +#else + SMC_SetPowerModeVlpr(SMC); +#endif + while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateVlpr) + { + } + /* Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKVLPR_CORE_CLOCK; +} diff --git a/hw/bsp/kinetis_k/boards/frdm_k64f/board/clock_config.h b/hw/bsp/kinetis_k/boards/frdm_k64f/board/clock_config.h new file mode 100644 index 000000000..88b141834 --- /dev/null +++ b/hw/bsp/kinetis_k/boards/frdm_k64f/board/clock_config.h @@ -0,0 +1,104 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _CLOCK_CONFIG_H_ +#define _CLOCK_CONFIG_H_ + +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define BOARD_XTAL0_CLK_HZ 50000000U /*!< Board xtal0 frequency in Hz */ + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes default configuration of clocks. + * + */ +void BOARD_InitBootClocks(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockRUN configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 120000000U /*!< Core clock frequency: 120000000Hz */ + +/*! @brief MCG set for BOARD_BootClockRUN configuration. + */ +extern const mcg_config_t mcgConfig_BOARD_BootClockRUN; +/*! @brief SIM module set for BOARD_BootClockRUN configuration. + */ +extern const sim_clock_config_t simConfig_BOARD_BootClockRUN; +/*! @brief OSC set for BOARD_BootClockRUN configuration. + */ +extern const osc_config_t oscConfig_BOARD_BootClockRUN; + +/******************************************************************************* + * API for BOARD_BootClockRUN configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockRUN(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ********************* Configuration BOARD_BootClockVLPR *********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockVLPR configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKVLPR_CORE_CLOCK 4000000U /*!< Core clock frequency: 4000000Hz */ + +/*! @brief MCG set for BOARD_BootClockVLPR configuration. + */ +extern const mcg_config_t mcgConfig_BOARD_BootClockVLPR; +/*! @brief SIM module set for BOARD_BootClockVLPR configuration. + */ +extern const sim_clock_config_t simConfig_BOARD_BootClockVLPR; +/*! @brief OSC set for BOARD_BootClockVLPR configuration. + */ +extern const osc_config_t oscConfig_BOARD_BootClockVLPR; + +/******************************************************************************* + * API for BOARD_BootClockVLPR configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockVLPR(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +#endif /* _CLOCK_CONFIG_H_ */ diff --git a/hw/bsp/kinetis_k/boards/frdm_k64f/board/pin_mux.c b/hw/bsp/kinetis_k/boards/frdm_k64f/board/pin_mux.c new file mode 100644 index 000000000..f4c245eef --- /dev/null +++ b/hw/bsp/kinetis_k/boards/frdm_k64f/board/pin_mux.c @@ -0,0 +1,852 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Pins v14.0 +processor: MK64FN1M0xxx12 +package_id: MK64FN1M0VLL12 +mcu_data: ksdk2_0 +processor_version: 14.0.0 +board: FRDM-K64F + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +#include "fsl_common.h" +#include "fsl_port.h" +#include "fsl_gpio.h" +#include "pin_mux.h" + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitBootPins + * Description : Calls initialization functions. + * + * END ****************************************************************************************************************/ +void BOARD_InitBootPins(void) +{ + BOARD_InitButtons(); + BOARD_InitLEDs(); + BOARD_InitDEBUG_UART(); +} + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitPins: +- options: {callFromInitBoot: 'false', prefix: BOARD_, coreID: core0, enableClock: 'true'} +- pin_list: [] + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitPins(void) +{ +} + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitButtons: +- options: {callFromInitBoot: 'true', prefix: BOARD_, coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: '78', peripheral: GPIOC, signal: 'GPIO, 6', pin_signal: CMP0_IN0/PTC6/LLWU_P10/SPI0_SOUT/PDB0_EXTRG/I2S0_RX_BCLK/FB_AD9/I2S0_MCLK, identifier: SW2, + direction: INPUT, slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: up, pull_enable: enable, passive_filter: disable} + - {pin_num: '38', peripheral: GPIOA, signal: 'GPIO, 4', pin_signal: PTA4/LLWU_P3/FTM0_CH1/NMI_b/EZP_CS_b, direction: INPUT, slew_rate: fast, open_drain: disable, + drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitButtons + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitButtons(void) +{ + /* Port A Clock Gate Control: Clock enabled */ + CLOCK_EnableClock(kCLOCK_PortA); + /* Port C Clock Gate Control: Clock enabled */ + CLOCK_EnableClock(kCLOCK_PortC); + + gpio_pin_config_t SW3_config = { + .pinDirection = kGPIO_DigitalInput, + .outputLogic = 0U + }; + /* Initialize GPIO functionality on pin PTA4 (pin 38) */ + GPIO_PinInit(BOARD_SW3_GPIO, BOARD_SW3_PIN, &SW3_config); + + gpio_pin_config_t SW2_config = { + .pinDirection = kGPIO_DigitalInput, + .outputLogic = 0U + }; + /* Initialize GPIO functionality on pin PTC6 (pin 78) */ + GPIO_PinInit(BOARD_SW2_GPIO, BOARD_SW2_PIN, &SW2_config); + + const port_pin_config_t SW3 = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as PTA4 */ + kPORT_MuxAsGpio, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTA4 (pin 38) is configured as PTA4 */ + PORT_SetPinConfig(BOARD_SW3_PORT, BOARD_SW3_PIN, &SW3); + + const port_pin_config_t SW2 = {/* Internal pull-up resistor is enabled */ + kPORT_PullUp, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as PTC6 */ + kPORT_MuxAsGpio, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTC6 (pin 78) is configured as PTC6 */ + PORT_SetPinConfig(BOARD_SW2_PORT, BOARD_SW2_PIN, &SW2); +} + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitLEDs: +- options: {callFromInitBoot: 'true', prefix: BOARD_, coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: '67', peripheral: GPIOB, signal: 'GPIO, 21', pin_signal: PTB21/SPI2_SCK/FB_AD30/CMP1_OUT, direction: OUTPUT, gpio_init_state: 'true', slew_rate: slow, + open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} + - {pin_num: '68', peripheral: GPIOB, signal: 'GPIO, 22', pin_signal: PTB22/SPI2_SOUT/FB_AD29/CMP2_OUT, direction: OUTPUT, gpio_init_state: 'true', slew_rate: slow, + open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} + - {pin_num: '33', peripheral: GPIOE, signal: 'GPIO, 26', pin_signal: PTE26/ENET_1588_CLKIN/UART4_CTS_b/RTC_CLKOUT/USB_CLKIN, direction: OUTPUT, gpio_init_state: 'true', + slew_rate: slow, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitLEDs + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitLEDs(void) +{ + /* Port B Clock Gate Control: Clock enabled */ + CLOCK_EnableClock(kCLOCK_PortB); + /* Port E Clock Gate Control: Clock enabled */ + CLOCK_EnableClock(kCLOCK_PortE); + + gpio_pin_config_t LED_BLUE_config = { + .pinDirection = kGPIO_DigitalOutput, + .outputLogic = 1U + }; + /* Initialize GPIO functionality on pin PTB21 (pin 67) */ + GPIO_PinInit(BOARD_LED_BLUE_GPIO, BOARD_LED_BLUE_PIN, &LED_BLUE_config); + + gpio_pin_config_t LED_RED_config = { + .pinDirection = kGPIO_DigitalOutput, + .outputLogic = 1U + }; + /* Initialize GPIO functionality on pin PTB22 (pin 68) */ + GPIO_PinInit(BOARD_LED_RED_GPIO, BOARD_LED_RED_PIN, &LED_RED_config); + + gpio_pin_config_t LED_GREEN_config = { + .pinDirection = kGPIO_DigitalOutput, + .outputLogic = 1U + }; + /* Initialize GPIO functionality on pin PTE26 (pin 33) */ + GPIO_PinInit(BOARD_LED_GREEN_GPIO, BOARD_LED_GREEN_PIN, &LED_GREEN_config); + + const port_pin_config_t LED_BLUE = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Slow slew rate is configured */ + kPORT_SlowSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as PTB21 */ + kPORT_MuxAsGpio, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTB21 (pin 67) is configured as PTB21 */ + PORT_SetPinConfig(BOARD_LED_BLUE_PORT, BOARD_LED_BLUE_PIN, &LED_BLUE); + + const port_pin_config_t LED_RED = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Slow slew rate is configured */ + kPORT_SlowSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as PTB22 */ + kPORT_MuxAsGpio, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTB22 (pin 68) is configured as PTB22 */ + PORT_SetPinConfig(BOARD_LED_RED_PORT, BOARD_LED_RED_PIN, &LED_RED); + + const port_pin_config_t LED_GREEN = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Slow slew rate is configured */ + kPORT_SlowSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as PTE26 */ + kPORT_MuxAsGpio, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTE26 (pin 33) is configured as PTE26 */ + PORT_SetPinConfig(BOARD_LED_GREEN_PORT, BOARD_LED_GREEN_PIN, &LED_GREEN); +} + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitDEBUG_UART: +- options: {callFromInitBoot: 'true', prefix: BOARD_, coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: '63', peripheral: UART0, signal: TX, pin_signal: PTB17/SPI1_SIN/UART0_TX/FTM_CLKIN1/FB_AD16/EWM_OUT_b, direction: OUTPUT, slew_rate: fast, open_drain: disable, + drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} + - {pin_num: '62', peripheral: UART0, signal: RX, pin_signal: PTB16/SPI1_SOUT/UART0_RX/FTM_CLKIN0/FB_AD17/EWM_IN, slew_rate: fast, open_drain: disable, drive_strength: low, + pull_select: down, pull_enable: disable, passive_filter: disable} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitDEBUG_UART + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitDEBUG_UART(void) +{ + /* Port B Clock Gate Control: Clock enabled */ + CLOCK_EnableClock(kCLOCK_PortB); + + const port_pin_config_t DEBUG_UART_RX = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as UART0_RX */ + kPORT_MuxAlt3, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTB16 (pin 62) is configured as UART0_RX */ + PORT_SetPinConfig(BOARD_DEBUG_UART_RX_PORT, BOARD_DEBUG_UART_RX_PIN, &DEBUG_UART_RX); + + const port_pin_config_t DEBUG_UART_TX = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as UART0_TX */ + kPORT_MuxAlt3, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTB17 (pin 63) is configured as UART0_TX */ + PORT_SetPinConfig(BOARD_DEBUG_UART_TX_PORT, BOARD_DEBUG_UART_TX_PIN, &DEBUG_UART_TX); + + SIM->SOPT5 = ((SIM->SOPT5 & + /* Mask bits to zero which are setting */ + (~(SIM_SOPT5_UART0TXSRC_MASK))) + + /* UART 0 transmit data source select: UART0_TX pin. */ + | SIM_SOPT5_UART0TXSRC(SOPT5_UART0TXSRC_UART_TX)); +} + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitOSC: +- options: {callFromInitBoot: 'false', prefix: BOARD_, coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: '50', peripheral: OSC, signal: EXTAL0, pin_signal: EXTAL0/PTA18/FTM0_FLT2/FTM_CLKIN0, identifier: EXTAL0, slew_rate: no_init, open_drain: no_init, drive_strength: no_init, + pull_select: no_init, pull_enable: no_init, passive_filter: no_init} + - {pin_num: '29', peripheral: RTC, signal: EXTAL32, pin_signal: EXTAL32} + - {pin_num: '28', peripheral: RTC, signal: XTAL32, pin_signal: XTAL32} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitOSC + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitOSC(void) +{ + /* Port A Clock Gate Control: Clock enabled */ + CLOCK_EnableClock(kCLOCK_PortA); + + /* PORTA18 (pin 50) is configured as EXTAL0 */ + PORT_SetPinMux(BOARD_EXTAL0_PORT, BOARD_EXTAL0_PIN, kPORT_PinDisabledOrAnalog); +} + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitACCEL: +- options: {callFromInitBoot: 'false', prefix: BOARD_, coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: '32', peripheral: I2C0, signal: SDA, pin_signal: ADC0_SE18/PTE25/UART4_RX/I2C0_SDA/EWM_IN, slew_rate: fast, open_drain: enable, drive_strength: low, + pull_select: up, pull_enable: enable, passive_filter: disable} + - {pin_num: '31', peripheral: I2C0, signal: SCL, pin_signal: ADC0_SE17/PTE24/UART4_TX/I2C0_SCL/EWM_OUT_b, slew_rate: fast, open_drain: enable, drive_strength: low, + pull_select: up, pull_enable: enable, passive_filter: disable} + - {pin_num: '78', peripheral: GPIOC, signal: 'GPIO, 6', pin_signal: CMP0_IN0/PTC6/LLWU_P10/SPI0_SOUT/PDB0_EXTRG/I2S0_RX_BCLK/FB_AD9/I2S0_MCLK, identifier: ACCEL_INT1, + direction: INPUT, slew_rate: fast, open_drain: enable, drive_strength: low, pull_select: up, pull_enable: enable, passive_filter: disable} + - {pin_num: '85', peripheral: GPIOC, signal: 'GPIO, 13', pin_signal: PTC13/UART4_CTS_b/FB_AD26, direction: INPUT, slew_rate: fast, open_drain: enable, drive_strength: low, + pull_select: up, pull_enable: enable, passive_filter: disable} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitACCEL + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitACCEL(void) +{ + /* Port C Clock Gate Control: Clock enabled */ + CLOCK_EnableClock(kCLOCK_PortC); + /* Port E Clock Gate Control: Clock enabled */ + CLOCK_EnableClock(kCLOCK_PortE); + + gpio_pin_config_t ACCEL_INT1_config = { + .pinDirection = kGPIO_DigitalInput, + .outputLogic = 0U + }; + /* Initialize GPIO functionality on pin PTC6 (pin 78) */ + GPIO_PinInit(BOARD_ACCEL_INT1_GPIO, BOARD_ACCEL_INT1_PIN, &ACCEL_INT1_config); + + gpio_pin_config_t ACCEL_INT2_config = { + .pinDirection = kGPIO_DigitalInput, + .outputLogic = 0U + }; + /* Initialize GPIO functionality on pin PTC13 (pin 85) */ + GPIO_PinInit(BOARD_ACCEL_INT2_GPIO, BOARD_ACCEL_INT2_PIN, &ACCEL_INT2_config); + + const port_pin_config_t ACCEL_INT2 = {/* Internal pull-up resistor is enabled */ + kPORT_PullUp, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is enabled */ + kPORT_OpenDrainEnable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as PTC13 */ + kPORT_MuxAsGpio, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTC13 (pin 85) is configured as PTC13 */ + PORT_SetPinConfig(BOARD_ACCEL_INT2_PORT, BOARD_ACCEL_INT2_PIN, &ACCEL_INT2); + + const port_pin_config_t ACCEL_INT1 = {/* Internal pull-up resistor is enabled */ + kPORT_PullUp, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is enabled */ + kPORT_OpenDrainEnable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as PTC6 */ + kPORT_MuxAsGpio, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTC6 (pin 78) is configured as PTC6 */ + PORT_SetPinConfig(BOARD_ACCEL_INT1_PORT, BOARD_ACCEL_INT1_PIN, &ACCEL_INT1); + + const port_pin_config_t ACCEL_SCL = {/* Internal pull-up resistor is enabled */ + kPORT_PullUp, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is enabled */ + kPORT_OpenDrainEnable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as I2C0_SCL */ + kPORT_MuxAlt5, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTE24 (pin 31) is configured as I2C0_SCL */ + PORT_SetPinConfig(BOARD_ACCEL_SCL_PORT, BOARD_ACCEL_SCL_PIN, &ACCEL_SCL); + + const port_pin_config_t ACCEL_SDA = {/* Internal pull-up resistor is enabled */ + kPORT_PullUp, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is enabled */ + kPORT_OpenDrainEnable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as I2C0_SDA */ + kPORT_MuxAlt5, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTE25 (pin 32) is configured as I2C0_SDA */ + PORT_SetPinConfig(BOARD_ACCEL_SDA_PORT, BOARD_ACCEL_SDA_PIN, &ACCEL_SDA); +} + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitENET: +- options: {callFromInitBoot: 'false', prefix: BOARD_, coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: '54', peripheral: ENET, signal: RMII_MDC, pin_signal: ADC0_SE9/ADC1_SE9/PTB1/I2C0_SDA/FTM1_CH1/RMII0_MDC/MII0_MDC/FTM1_QD_PHB, slew_rate: fast, open_drain: disable, + drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} + - {pin_num: '53', peripheral: ENET, signal: RMII_MDIO, pin_signal: ADC0_SE8/ADC1_SE8/PTB0/LLWU_P5/I2C0_SCL/FTM1_CH0/RMII0_MDIO/MII0_MDIO/FTM1_QD_PHA, slew_rate: fast, + open_drain: enable, drive_strength: low, pull_select: up, pull_enable: enable, passive_filter: disable} + - {pin_num: '43', peripheral: ENET, signal: RMII_RXD0, pin_signal: CMP2_IN1/PTA13/LLWU_P4/CAN0_RX/FTM1_CH1/RMII0_RXD0/MII0_RXD0/I2C2_SDA/I2S0_TX_FS/FTM1_QD_PHB, + slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} + - {pin_num: '42', peripheral: ENET, signal: RMII_RXD1, pin_signal: CMP2_IN0/PTA12/CAN0_TX/FTM1_CH0/RMII0_RXD1/MII0_RXD1/I2C2_SCL/I2S0_TXD0/FTM1_QD_PHA, slew_rate: fast, + open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} + - {pin_num: '39', peripheral: ENET, signal: RMII_RXER, pin_signal: PTA5/USB_CLKIN/FTM0_CH2/RMII0_RXER/MII0_RXER/CMP2_OUT/I2S0_TX_BCLK/JTAG_TRST_b, slew_rate: fast, + open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} + - {pin_num: '46', peripheral: ENET, signal: RMII_TXD0, pin_signal: PTA16/SPI0_SOUT/UART0_CTS_b/UART0_COL_b/RMII0_TXD0/MII0_TXD0/I2S0_RX_FS/I2S0_RXD1, slew_rate: fast, + open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} + - {pin_num: '47', peripheral: ENET, signal: RMII_TXD1, pin_signal: ADC1_SE17/PTA17/SPI0_SIN/UART0_RTS_b/RMII0_TXD1/MII0_TXD1/I2S0_MCLK, slew_rate: fast, open_drain: disable, + drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} + - {pin_num: '45', peripheral: ENET, signal: RMII_TXEN, pin_signal: PTA15/SPI0_SCK/UART0_RX/RMII0_TXEN/MII0_TXEN/I2S0_RXD0, slew_rate: fast, open_drain: disable, + drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} + - {pin_num: '44', peripheral: ENET, signal: RMII_CRS_DV, pin_signal: PTA14/SPI0_PCS0/UART0_TX/RMII0_CRS_DV/MII0_RXDV/I2C2_SCL/I2S0_RX_BCLK/I2S0_TXD1, slew_rate: fast, + open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} + - {pin_num: '50', peripheral: ENET, signal: RMII_CLKIN, pin_signal: EXTAL0/PTA18/FTM0_FLT2/FTM_CLKIN0, identifier: RMII_RXCLK, slew_rate: fast, open_drain: disable, + drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitENET + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitENET(void) +{ + /* Port A Clock Gate Control: Clock enabled */ + CLOCK_EnableClock(kCLOCK_PortA); + /* Port B Clock Gate Control: Clock enabled */ + CLOCK_EnableClock(kCLOCK_PortB); + + const port_pin_config_t RMII0_RXD1 = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as RMII0_RXD1 */ + kPORT_MuxAlt4, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTA12 (pin 42) is configured as RMII0_RXD1 */ + PORT_SetPinConfig(BOARD_RMII0_RXD1_PORT, BOARD_RMII0_RXD1_PIN, &RMII0_RXD1); + + const port_pin_config_t RMII0_RXD0 = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as RMII0_RXD0 */ + kPORT_MuxAlt4, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTA13 (pin 43) is configured as RMII0_RXD0 */ + PORT_SetPinConfig(BOARD_RMII0_RXD0_PORT, BOARD_RMII0_RXD0_PIN, &RMII0_RXD0); + + const port_pin_config_t RMII0_CRS_DV = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as RMII0_CRS_DV */ + kPORT_MuxAlt4, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTA14 (pin 44) is configured as RMII0_CRS_DV */ + PORT_SetPinConfig(BOARD_RMII0_CRS_DV_PORT, BOARD_RMII0_CRS_DV_PIN, &RMII0_CRS_DV); + + const port_pin_config_t RMII0_TXEN = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as RMII0_TXEN */ + kPORT_MuxAlt4, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTA15 (pin 45) is configured as RMII0_TXEN */ + PORT_SetPinConfig(BOARD_RMII0_TXEN_PORT, BOARD_RMII0_TXEN_PIN, &RMII0_TXEN); + + const port_pin_config_t RMII0_TXD0 = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as RMII0_TXD0 */ + kPORT_MuxAlt4, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTA16 (pin 46) is configured as RMII0_TXD0 */ + PORT_SetPinConfig(BOARD_RMII0_TXD0_PORT, BOARD_RMII0_TXD0_PIN, &RMII0_TXD0); + + const port_pin_config_t RMII0_TXD1 = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as RMII0_TXD1 */ + kPORT_MuxAlt4, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTA17 (pin 47) is configured as RMII0_TXD1 */ + PORT_SetPinConfig(BOARD_RMII0_TXD1_PORT, BOARD_RMII0_TXD1_PIN, &RMII0_TXD1); + + const port_pin_config_t RMII_RXCLK = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as EXTAL0 */ + kPORT_PinDisabledOrAnalog, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTA18 (pin 50) is configured as EXTAL0 */ + PORT_SetPinConfig(BOARD_RMII_RXCLK_PORT, BOARD_RMII_RXCLK_PIN, &RMII_RXCLK); + + const port_pin_config_t RMII0_RXER = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as RMII0_RXER */ + kPORT_MuxAlt4, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTA5 (pin 39) is configured as RMII0_RXER */ + PORT_SetPinConfig(BOARD_RMII0_RXER_PORT, BOARD_RMII0_RXER_PIN, &RMII0_RXER); + + const port_pin_config_t RMII0_MDIO = {/* Internal pull-up resistor is enabled */ + kPORT_PullUp, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is enabled */ + kPORT_OpenDrainEnable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as RMII0_MDIO */ + kPORT_MuxAlt4, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTB0 (pin 53) is configured as RMII0_MDIO */ + PORT_SetPinConfig(BOARD_RMII0_MDIO_PORT, BOARD_RMII0_MDIO_PIN, &RMII0_MDIO); + + const port_pin_config_t RMII0_MDC = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as RMII0_MDC */ + kPORT_MuxAlt4, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTB1 (pin 54) is configured as RMII0_MDC */ + PORT_SetPinConfig(BOARD_RMII0_MDC_PORT, BOARD_RMII0_MDC_PIN, &RMII0_MDC); + + SIM->SOPT2 = ((SIM->SOPT2 & + /* Mask bits to zero which are setting */ + (~(SIM_SOPT2_RMIISRC_MASK))) + + /* RMII clock source select: EXTAL clock. */ + | SIM_SOPT2_RMIISRC(SOPT2_RMIISRC_EXTAL)); +} + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitSDHC: +- options: {callFromInitBoot: 'false', prefix: BOARD_, coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: '1', peripheral: SDHC, signal: 'DATA, 1', pin_signal: ADC1_SE4a/PTE0/SPI1_PCS1/UART1_TX/SDHC0_D1/TRACE_CLKOUT/I2C1_SDA/RTC_CLKOUT, slew_rate: fast, + open_drain: disable, drive_strength: high, pull_select: up, pull_enable: enable, passive_filter: disable} + - {pin_num: '2', peripheral: SDHC, signal: 'DATA, 0', pin_signal: ADC1_SE5a/PTE1/LLWU_P0/SPI1_SOUT/UART1_RX/SDHC0_D0/TRACE_D3/I2C1_SCL/SPI1_SIN, slew_rate: fast, + open_drain: disable, drive_strength: high, pull_select: up, pull_enable: enable, passive_filter: disable} + - {pin_num: '3', peripheral: SDHC, signal: DCLK, pin_signal: ADC0_DP2/ADC1_SE6a/PTE2/LLWU_P1/SPI1_SCK/UART1_CTS_b/SDHC0_DCLK/TRACE_D2, slew_rate: fast, open_drain: disable, + drive_strength: high, pull_select: up, pull_enable: enable, passive_filter: disable} + - {pin_num: '4', peripheral: SDHC, signal: CMD, pin_signal: ADC0_DM2/ADC1_SE7a/PTE3/SPI1_SIN/UART1_RTS_b/SDHC0_CMD/TRACE_D1/SPI1_SOUT, slew_rate: fast, open_drain: disable, + drive_strength: high, pull_select: up, pull_enable: enable, passive_filter: disable} + - {pin_num: '5', peripheral: SDHC, signal: 'DATA, 3', pin_signal: PTE4/LLWU_P2/SPI1_PCS0/UART3_TX/SDHC0_D3/TRACE_D0, slew_rate: fast, open_drain: disable, drive_strength: high, + pull_select: up, pull_enable: enable, passive_filter: disable} + - {pin_num: '6', peripheral: SDHC, signal: 'DATA, 2', pin_signal: PTE5/SPI1_PCS2/UART3_RX/SDHC0_D2/FTM3_CH0, slew_rate: fast, open_drain: disable, drive_strength: high, + pull_select: up, pull_enable: enable, passive_filter: disable} + - {pin_num: '7', peripheral: GPIOE, signal: 'GPIO, 6', pin_signal: PTE6/SPI1_PCS3/UART3_CTS_b/I2S0_MCLK/FTM3_CH1/USB_SOF_OUT, direction: INPUT, slew_rate: slow, + open_drain: disable, drive_strength: low, pull_select: down, pull_enable: enable, passive_filter: disable} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitSDHC + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitSDHC(void) +{ + /* Port E Clock Gate Control: Clock enabled */ + CLOCK_EnableClock(kCLOCK_PortE); + + gpio_pin_config_t SDHC_CD_config = { + .pinDirection = kGPIO_DigitalInput, + .outputLogic = 0U + }; + /* Initialize GPIO functionality on pin PTE6 (pin 7) */ + GPIO_PinInit(BOARD_SDHC_CD_GPIO, BOARD_SDHC_CD_PIN, &SDHC_CD_config); + + const port_pin_config_t SDHC0_D1 = {/* Internal pull-up resistor is enabled */ + kPORT_PullUp, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* High drive strength is configured */ + kPORT_HighDriveStrength, + /* Pin is configured as SDHC0_D1 */ + kPORT_MuxAlt4, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTE0 (pin 1) is configured as SDHC0_D1 */ + PORT_SetPinConfig(BOARD_SDHC0_D1_PORT, BOARD_SDHC0_D1_PIN, &SDHC0_D1); + + const port_pin_config_t SDHC0_D0 = {/* Internal pull-up resistor is enabled */ + kPORT_PullUp, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* High drive strength is configured */ + kPORT_HighDriveStrength, + /* Pin is configured as SDHC0_D0 */ + kPORT_MuxAlt4, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTE1 (pin 2) is configured as SDHC0_D0 */ + PORT_SetPinConfig(BOARD_SDHC0_D0_PORT, BOARD_SDHC0_D0_PIN, &SDHC0_D0); + + const port_pin_config_t SDHC0_DCLK = {/* Internal pull-up resistor is enabled */ + kPORT_PullUp, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* High drive strength is configured */ + kPORT_HighDriveStrength, + /* Pin is configured as SDHC0_DCLK */ + kPORT_MuxAlt4, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTE2 (pin 3) is configured as SDHC0_DCLK */ + PORT_SetPinConfig(BOARD_SDHC0_DCLK_PORT, BOARD_SDHC0_DCLK_PIN, &SDHC0_DCLK); + + const port_pin_config_t SDHC0_CMD = {/* Internal pull-up resistor is enabled */ + kPORT_PullUp, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* High drive strength is configured */ + kPORT_HighDriveStrength, + /* Pin is configured as SDHC0_CMD */ + kPORT_MuxAlt4, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTE3 (pin 4) is configured as SDHC0_CMD */ + PORT_SetPinConfig(BOARD_SDHC0_CMD_PORT, BOARD_SDHC0_CMD_PIN, &SDHC0_CMD); + + const port_pin_config_t SDHC0_D3 = {/* Internal pull-up resistor is enabled */ + kPORT_PullUp, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* High drive strength is configured */ + kPORT_HighDriveStrength, + /* Pin is configured as SDHC0_D3 */ + kPORT_MuxAlt4, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTE4 (pin 5) is configured as SDHC0_D3 */ + PORT_SetPinConfig(BOARD_SDHC0_D3_PORT, BOARD_SDHC0_D3_PIN, &SDHC0_D3); + + const port_pin_config_t SDHC0_D2 = {/* Internal pull-up resistor is enabled */ + kPORT_PullUp, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* High drive strength is configured */ + kPORT_HighDriveStrength, + /* Pin is configured as SDHC0_D2 */ + kPORT_MuxAlt4, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTE5 (pin 6) is configured as SDHC0_D2 */ + PORT_SetPinConfig(BOARD_SDHC0_D2_PORT, BOARD_SDHC0_D2_PIN, &SDHC0_D2); + + const port_pin_config_t SDHC_CD = {/* Internal pull-down resistor is enabled */ + kPORT_PullDown, + /* Slow slew rate is configured */ + kPORT_SlowSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as PTE6 */ + kPORT_MuxAsGpio, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTE6 (pin 7) is configured as PTE6 */ + PORT_SetPinConfig(BOARD_SDHC_CD_PORT, BOARD_SDHC_CD_PIN, &SDHC_CD); +} + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitUSB: +- options: {callFromInitBoot: 'false', prefix: BOARD_, coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: '10', peripheral: USB0, signal: DP, pin_signal: USB0_DP} + - {pin_num: '11', peripheral: USB0, signal: DM, pin_signal: USB0_DM} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitUSB + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitUSB(void) +{ +} +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/kinetis_k/boards/frdm_k64f/board/pin_mux.h b/hw/bsp/kinetis_k/boards/frdm_k64f/board/pin_mux.h new file mode 100644 index 000000000..6d64832ba --- /dev/null +++ b/hw/bsp/kinetis_k/boards/frdm_k64f/board/pin_mux.h @@ -0,0 +1,645 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _PIN_MUX_H_ +#define _PIN_MUX_H_ + +/*********************************************************************************************************************** + * Definitions + **********************************************************************************************************************/ + +/*! @brief Direction type */ +typedef enum _pin_mux_direction +{ + kPIN_MUX_DirectionInput = 0U, /* Input direction */ + kPIN_MUX_DirectionOutput = 1U, /* Output direction */ + kPIN_MUX_DirectionInputOrOutput = 2U /* Input or output direction */ +} pin_mux_direction_t; + +/*! + * @addtogroup pin_mux + * @{ + */ + +/*********************************************************************************************************************** + * API + **********************************************************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Calls initialization functions. + * + */ +void BOARD_InitBootPins(void); + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitPins(void); + +/*! @name PORTC6 (number 78), U8[11]/SW2 + @{ */ +/* Routed pin properties */ +#define BOARD_SW2_PERIPHERAL GPIOC /*!<@brief Peripheral name */ +#define BOARD_SW2_SIGNAL GPIO /*!<@brief Signal name */ +#define BOARD_SW2_CHANNEL 6 /*!<@brief Signal channel */ +#define BOARD_SW2_PIN_NAME PTC6 /*!<@brief Routed pin name */ +#define BOARD_SW2_LABEL "U8[11]/SW2" /*!<@brief Label */ +#define BOARD_SW2_NAME "SW2" /*!<@brief Identifier */ +#define BOARD_SW2_DIRECTION kPIN_MUX_DirectionInput /*!<@brief Direction */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_SW2_GPIO GPIOC /*!<@brief GPIO peripheral base pointer */ +#define BOARD_SW2_GPIO_PIN 6U /*!<@brief GPIO pin number */ +#define BOARD_SW2_GPIO_PIN_MASK (1U << 6U) /*!<@brief GPIO pin mask */ + +/* Symbols to be used with PORT driver */ +#define BOARD_SW2_PORT PORTC /*!<@brief PORT peripheral base pointer */ +#define BOARD_SW2_PIN 6U /*!<@brief PORT pin number */ +#define BOARD_SW2_PIN_MASK (1U << 6U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTA4 (number 38), SW3 + @{ */ +/* Routed pin properties */ +#define BOARD_SW3_PERIPHERAL GPIOA /*!<@brief Peripheral name */ +#define BOARD_SW3_SIGNAL GPIO /*!<@brief Signal name */ +#define BOARD_SW3_CHANNEL 4 /*!<@brief Signal channel */ +#define BOARD_SW3_PIN_NAME PTA4 /*!<@brief Routed pin name */ +#define BOARD_SW3_LABEL "SW3" /*!<@brief Label */ +#define BOARD_SW3_NAME "SW3" /*!<@brief Identifier */ +#define BOARD_SW3_DIRECTION kPIN_MUX_DirectionInput /*!<@brief Direction */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_SW3_GPIO GPIOA /*!<@brief GPIO peripheral base pointer */ +#define BOARD_SW3_GPIO_PIN 4U /*!<@brief GPIO pin number */ +#define BOARD_SW3_GPIO_PIN_MASK (1U << 4U) /*!<@brief GPIO pin mask */ + +/* Symbols to be used with PORT driver */ +#define BOARD_SW3_PORT PORTA /*!<@brief PORT peripheral base pointer */ +#define BOARD_SW3_PIN 4U /*!<@brief PORT pin number */ +#define BOARD_SW3_PIN_MASK (1U << 4U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitButtons(void); + +/*! @name PORTB21 (number 67), D12[3]/LEDRGB_BLUE + @{ */ +/* Routed pin properties */ +#define BOARD_LED_BLUE_PERIPHERAL GPIOB /*!<@brief Peripheral name */ +#define BOARD_LED_BLUE_SIGNAL GPIO /*!<@brief Signal name */ +#define BOARD_LED_BLUE_CHANNEL 21 /*!<@brief Signal channel */ +#define BOARD_LED_BLUE_PIN_NAME PTB21 /*!<@brief Routed pin name */ +#define BOARD_LED_BLUE_LABEL "D12[3]/LEDRGB_BLUE" /*!<@brief Label */ +#define BOARD_LED_BLUE_NAME "LED_BLUE" /*!<@brief Identifier */ +#define BOARD_LED_BLUE_DIRECTION kPIN_MUX_DirectionOutput /*!<@brief Direction */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_LED_BLUE_GPIO GPIOB /*!<@brief GPIO peripheral base pointer */ +#define BOARD_LED_BLUE_GPIO_PIN 21U /*!<@brief GPIO pin number */ +#define BOARD_LED_BLUE_GPIO_PIN_MASK (1U << 21U) /*!<@brief GPIO pin mask */ + +/* Symbols to be used with PORT driver */ +#define BOARD_LED_BLUE_PORT PORTB /*!<@brief PORT peripheral base pointer */ +#define BOARD_LED_BLUE_PIN 21U /*!<@brief PORT pin number */ +#define BOARD_LED_BLUE_PIN_MASK (1U << 21U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTB22 (number 68), D12[1]/LEDRGB_RED + @{ */ +/* Routed pin properties */ +#define BOARD_LED_RED_PERIPHERAL GPIOB /*!<@brief Peripheral name */ +#define BOARD_LED_RED_SIGNAL GPIO /*!<@brief Signal name */ +#define BOARD_LED_RED_CHANNEL 22 /*!<@brief Signal channel */ +#define BOARD_LED_RED_PIN_NAME PTB22 /*!<@brief Routed pin name */ +#define BOARD_LED_RED_LABEL "D12[1]/LEDRGB_RED" /*!<@brief Label */ +#define BOARD_LED_RED_NAME "LED_RED" /*!<@brief Identifier */ +#define BOARD_LED_RED_DIRECTION kPIN_MUX_DirectionOutput /*!<@brief Direction */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_LED_RED_GPIO GPIOB /*!<@brief GPIO peripheral base pointer */ +#define BOARD_LED_RED_GPIO_PIN 22U /*!<@brief GPIO pin number */ +#define BOARD_LED_RED_GPIO_PIN_MASK (1U << 22U) /*!<@brief GPIO pin mask */ + +/* Symbols to be used with PORT driver */ +#define BOARD_LED_RED_PORT PORTB /*!<@brief PORT peripheral base pointer */ +#define BOARD_LED_RED_PIN 22U /*!<@brief PORT pin number */ +#define BOARD_LED_RED_PIN_MASK (1U << 22U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTE26 (number 33), J2[1]/D12[4]/LEDRGB_GREEN + @{ */ +/* Routed pin properties */ +#define BOARD_LED_GREEN_PERIPHERAL GPIOE /*!<@brief Peripheral name */ +#define BOARD_LED_GREEN_SIGNAL GPIO /*!<@brief Signal name */ +#define BOARD_LED_GREEN_CHANNEL 26 /*!<@brief Signal channel */ +#define BOARD_LED_GREEN_PIN_NAME PTE26 /*!<@brief Routed pin name */ +#define BOARD_LED_GREEN_LABEL "J2[1]/D12[4]/LEDRGB_GREEN" /*!<@brief Label */ +#define BOARD_LED_GREEN_NAME "LED_GREEN" /*!<@brief Identifier */ +#define BOARD_LED_GREEN_DIRECTION kPIN_MUX_DirectionOutput /*!<@brief Direction */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_LED_GREEN_GPIO GPIOE /*!<@brief GPIO peripheral base pointer */ +#define BOARD_LED_GREEN_GPIO_PIN 26U /*!<@brief GPIO pin number */ +#define BOARD_LED_GREEN_GPIO_PIN_MASK (1U << 26U) /*!<@brief GPIO pin mask */ + +/* Symbols to be used with PORT driver */ +#define BOARD_LED_GREEN_PORT PORTE /*!<@brief PORT peripheral base pointer */ +#define BOARD_LED_GREEN_PIN 26U /*!<@brief PORT pin number */ +#define BOARD_LED_GREEN_PIN_MASK (1U << 26U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitLEDs(void); + +#define SOPT5_UART0TXSRC_UART_TX 0x00u /*!<@brief UART 0 transmit data source select: UART0_TX pin */ + +/*! @name PORTB17 (number 63), U10[1]/UART0_TX + @{ */ +/* Routed pin properties */ +#define BOARD_DEBUG_UART_TX_PERIPHERAL UART0 /*!<@brief Peripheral name */ +#define BOARD_DEBUG_UART_TX_SIGNAL TX /*!<@brief Signal name */ +#define BOARD_DEBUG_UART_TX_PIN_NAME UART0_TX /*!<@brief Routed pin name */ +#define BOARD_DEBUG_UART_TX_LABEL "U10[1]/UART0_TX" /*!<@brief Label */ +#define BOARD_DEBUG_UART_TX_NAME "DEBUG_UART_TX" /*!<@brief Identifier */ +#define BOARD_DEBUG_UART_TX_DIRECTION kPIN_MUX_DirectionOutput /*!<@brief Direction */ + +/* Symbols to be used with PORT driver */ +#define BOARD_DEBUG_UART_TX_PORT PORTB /*!<@brief PORT peripheral base pointer */ +#define BOARD_DEBUG_UART_TX_PIN 17U /*!<@brief PORT pin number */ +#define BOARD_DEBUG_UART_TX_PIN_MASK (1U << 17U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTB16 (number 62), U7[4]/UART0_RX + @{ */ +/* Routed pin properties */ +#define BOARD_DEBUG_UART_RX_PERIPHERAL UART0 /*!<@brief Peripheral name */ +#define BOARD_DEBUG_UART_RX_SIGNAL RX /*!<@brief Signal name */ +#define BOARD_DEBUG_UART_RX_PIN_NAME UART0_RX /*!<@brief Routed pin name */ +#define BOARD_DEBUG_UART_RX_LABEL "U7[4]/UART0_RX" /*!<@brief Label */ +#define BOARD_DEBUG_UART_RX_NAME "DEBUG_UART_RX" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_DEBUG_UART_RX_PORT PORTB /*!<@brief PORT peripheral base pointer */ +#define BOARD_DEBUG_UART_RX_PIN 16U /*!<@brief PORT pin number */ +#define BOARD_DEBUG_UART_RX_PIN_MASK (1U << 16U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitDEBUG_UART(void); + +/*! @name PORTA18 (number 50), U13[16]/RMII_RXCLK + @{ */ +/* Routed pin properties */ +#define BOARD_EXTAL0_PERIPHERAL OSC /*!<@brief Peripheral name */ +#define BOARD_EXTAL0_SIGNAL EXTAL0 /*!<@brief Signal name */ +#define BOARD_EXTAL0_PIN_NAME EXTAL0 /*!<@brief Routed pin name */ +#define BOARD_EXTAL0_LABEL "U13[16]/RMII_RXCLK" /*!<@brief Label */ +#define BOARD_EXTAL0_NAME "EXTAL0" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_EXTAL0_PORT PORTA /*!<@brief PORT peripheral base pointer */ +#define BOARD_EXTAL0_PIN 18U /*!<@brief PORT pin number */ +#define BOARD_EXTAL0_PIN_MASK (1U << 18U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name EXTAL32 (number 29), Y3[2]/EXTAL32_RTC + @{ */ +/* Routed pin properties */ +#define BOARD_ETAL32K_PERIPHERAL RTC /*!<@brief Peripheral name */ +#define BOARD_ETAL32K_SIGNAL EXTAL32 /*!<@brief Signal name */ +#define BOARD_ETAL32K_PIN_NAME EXTAL32 /*!<@brief Routed pin name */ +#define BOARD_ETAL32K_LABEL "Y3[2]/EXTAL32_RTC" /*!<@brief Label */ +#define BOARD_ETAL32K_NAME "ETAL32K" /*!<@brief Identifier */ + /* @} */ + +/*! @name XTAL32 (number 28), Y3[1]/XTAL32_RTC + @{ */ +/* Routed pin properties */ +#define BOARD_XTAL32K_PERIPHERAL RTC /*!<@brief Peripheral name */ +#define BOARD_XTAL32K_SIGNAL XTAL32 /*!<@brief Signal name */ +#define BOARD_XTAL32K_PIN_NAME XTAL32 /*!<@brief Routed pin name */ +#define BOARD_XTAL32K_LABEL "Y3[1]/XTAL32_RTC" /*!<@brief Label */ +#define BOARD_XTAL32K_NAME "XTAL32K" /*!<@brief Identifier */ + /* @} */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitOSC(void); + +/*! @name PORTE25 (number 32), J2[18]/U8[6]/I2C0_SDA + @{ */ +/* Routed pin properties */ +#define BOARD_ACCEL_SDA_PERIPHERAL I2C0 /*!<@brief Peripheral name */ +#define BOARD_ACCEL_SDA_SIGNAL SDA /*!<@brief Signal name */ +#define BOARD_ACCEL_SDA_PIN_NAME I2C0_SDA /*!<@brief Routed pin name */ +#define BOARD_ACCEL_SDA_LABEL "J2[18]/U8[6]/I2C0_SDA" /*!<@brief Label */ +#define BOARD_ACCEL_SDA_NAME "ACCEL_SDA" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_ACCEL_SDA_PORT PORTE /*!<@brief PORT peripheral base pointer */ +#define BOARD_ACCEL_SDA_PIN 25U /*!<@brief PORT pin number */ +#define BOARD_ACCEL_SDA_PIN_MASK (1U << 25U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTE24 (number 31), J2[20]/U8[4]/I2C0_SCL + @{ */ +/* Routed pin properties */ +#define BOARD_ACCEL_SCL_PERIPHERAL I2C0 /*!<@brief Peripheral name */ +#define BOARD_ACCEL_SCL_SIGNAL SCL /*!<@brief Signal name */ +#define BOARD_ACCEL_SCL_PIN_NAME I2C0_SCL /*!<@brief Routed pin name */ +#define BOARD_ACCEL_SCL_LABEL "J2[20]/U8[4]/I2C0_SCL" /*!<@brief Label */ +#define BOARD_ACCEL_SCL_NAME "ACCEL_SCL" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_ACCEL_SCL_PORT PORTE /*!<@brief PORT peripheral base pointer */ +#define BOARD_ACCEL_SCL_PIN 24U /*!<@brief PORT pin number */ +#define BOARD_ACCEL_SCL_PIN_MASK (1U << 24U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTC6 (number 78), U8[11]/SW2 + @{ */ +/* Routed pin properties */ +#define BOARD_ACCEL_INT1_PERIPHERAL GPIOC /*!<@brief Peripheral name */ +#define BOARD_ACCEL_INT1_SIGNAL GPIO /*!<@brief Signal name */ +#define BOARD_ACCEL_INT1_CHANNEL 6 /*!<@brief Signal channel */ +#define BOARD_ACCEL_INT1_PIN_NAME PTC6 /*!<@brief Routed pin name */ +#define BOARD_ACCEL_INT1_LABEL "U8[11]/SW2" /*!<@brief Label */ +#define BOARD_ACCEL_INT1_NAME "ACCEL_INT1" /*!<@brief Identifier */ +#define BOARD_ACCEL_INT1_DIRECTION kPIN_MUX_DirectionInput /*!<@brief Direction */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_ACCEL_INT1_GPIO GPIOC /*!<@brief GPIO peripheral base pointer */ +#define BOARD_ACCEL_INT1_GPIO_PIN 6U /*!<@brief GPIO pin number */ +#define BOARD_ACCEL_INT1_GPIO_PIN_MASK (1U << 6U) /*!<@brief GPIO pin mask */ + +/* Symbols to be used with PORT driver */ +#define BOARD_ACCEL_INT1_PORT PORTC /*!<@brief PORT peripheral base pointer */ +#define BOARD_ACCEL_INT1_PIN 6U /*!<@brief PORT pin number */ +#define BOARD_ACCEL_INT1_PIN_MASK (1U << 6U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTC13 (number 85), U8[9] + @{ */ +/* Routed pin properties */ +#define BOARD_ACCEL_INT2_PERIPHERAL GPIOC /*!<@brief Peripheral name */ +#define BOARD_ACCEL_INT2_SIGNAL GPIO /*!<@brief Signal name */ +#define BOARD_ACCEL_INT2_CHANNEL 13 /*!<@brief Signal channel */ +#define BOARD_ACCEL_INT2_PIN_NAME PTC13 /*!<@brief Routed pin name */ +#define BOARD_ACCEL_INT2_LABEL "U8[9]" /*!<@brief Label */ +#define BOARD_ACCEL_INT2_NAME "ACCEL_INT2" /*!<@brief Identifier */ +#define BOARD_ACCEL_INT2_DIRECTION kPIN_MUX_DirectionInput /*!<@brief Direction */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_ACCEL_INT2_GPIO GPIOC /*!<@brief GPIO peripheral base pointer */ +#define BOARD_ACCEL_INT2_GPIO_PIN 13U /*!<@brief GPIO pin number */ +#define BOARD_ACCEL_INT2_GPIO_PIN_MASK (1U << 13U) /*!<@brief GPIO pin mask */ + +/* Symbols to be used with PORT driver */ +#define BOARD_ACCEL_INT2_PORT PORTC /*!<@brief PORT peripheral base pointer */ +#define BOARD_ACCEL_INT2_PIN 13U /*!<@brief PORT pin number */ +#define BOARD_ACCEL_INT2_PIN_MASK (1U << 13U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitACCEL(void); + +#define SOPT2_RMIISRC_EXTAL 0x00u /*!<@brief RMII clock source select: EXTAL clock */ + +/*! @name PORTB1 (number 54), U13[11]/RMII0_MDC + @{ */ +/* Routed pin properties */ +#define BOARD_RMII0_MDC_PERIPHERAL ENET /*!<@brief Peripheral name */ +#define BOARD_RMII0_MDC_SIGNAL RMII_MDC /*!<@brief Signal name */ +#define BOARD_RMII0_MDC_PIN_NAME RMII0_MDC /*!<@brief Routed pin name */ +#define BOARD_RMII0_MDC_LABEL "U13[11]/RMII0_MDC" /*!<@brief Label */ +#define BOARD_RMII0_MDC_NAME "RMII0_MDC" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_RMII0_MDC_PORT PORTB /*!<@brief PORT peripheral base pointer */ +#define BOARD_RMII0_MDC_PIN 1U /*!<@brief PORT pin number */ +#define BOARD_RMII0_MDC_PIN_MASK (1U << 1U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTB0 (number 53), U13[10]/RMII0_MDIO + @{ */ +/* Routed pin properties */ +#define BOARD_RMII0_MDIO_PERIPHERAL ENET /*!<@brief Peripheral name */ +#define BOARD_RMII0_MDIO_SIGNAL RMII_MDIO /*!<@brief Signal name */ +#define BOARD_RMII0_MDIO_PIN_NAME RMII0_MDIO /*!<@brief Routed pin name */ +#define BOARD_RMII0_MDIO_LABEL "U13[10]/RMII0_MDIO" /*!<@brief Label */ +#define BOARD_RMII0_MDIO_NAME "RMII0_MDIO" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_RMII0_MDIO_PORT PORTB /*!<@brief PORT peripheral base pointer */ +#define BOARD_RMII0_MDIO_PIN 0U /*!<@brief PORT pin number */ +#define BOARD_RMII0_MDIO_PIN_MASK (1U << 0U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTA13 (number 43), U13[13]/RMII0_RXD_0 + @{ */ +/* Routed pin properties */ +#define BOARD_RMII0_RXD0_PERIPHERAL ENET /*!<@brief Peripheral name */ +#define BOARD_RMII0_RXD0_SIGNAL RMII_RXD0 /*!<@brief Signal name */ +#define BOARD_RMII0_RXD0_PIN_NAME RMII0_RXD0 /*!<@brief Routed pin name */ +#define BOARD_RMII0_RXD0_LABEL "U13[13]/RMII0_RXD_0" /*!<@brief Label */ +#define BOARD_RMII0_RXD0_NAME "RMII0_RXD0" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_RMII0_RXD0_PORT PORTA /*!<@brief PORT peripheral base pointer */ +#define BOARD_RMII0_RXD0_PIN 13U /*!<@brief PORT pin number */ +#define BOARD_RMII0_RXD0_PIN_MASK (1U << 13U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTA12 (number 42), U13[12]/RMII0_RXD_1 + @{ */ +/* Routed pin properties */ +#define BOARD_RMII0_RXD1_PERIPHERAL ENET /*!<@brief Peripheral name */ +#define BOARD_RMII0_RXD1_SIGNAL RMII_RXD1 /*!<@brief Signal name */ +#define BOARD_RMII0_RXD1_PIN_NAME RMII0_RXD1 /*!<@brief Routed pin name */ +#define BOARD_RMII0_RXD1_LABEL "U13[12]/RMII0_RXD_1" /*!<@brief Label */ +#define BOARD_RMII0_RXD1_NAME "RMII0_RXD1" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_RMII0_RXD1_PORT PORTA /*!<@brief PORT peripheral base pointer */ +#define BOARD_RMII0_RXD1_PIN 12U /*!<@brief PORT pin number */ +#define BOARD_RMII0_RXD1_PIN_MASK (1U << 12U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTA5 (number 39), U13[17]/RMII0_RXER + @{ */ +/* Routed pin properties */ +#define BOARD_RMII0_RXER_PERIPHERAL ENET /*!<@brief Peripheral name */ +#define BOARD_RMII0_RXER_SIGNAL RMII_RXER /*!<@brief Signal name */ +#define BOARD_RMII0_RXER_PIN_NAME RMII0_RXER /*!<@brief Routed pin name */ +#define BOARD_RMII0_RXER_LABEL "U13[17]/RMII0_RXER" /*!<@brief Label */ +#define BOARD_RMII0_RXER_NAME "RMII0_RXER" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_RMII0_RXER_PORT PORTA /*!<@brief PORT peripheral base pointer */ +#define BOARD_RMII0_RXER_PIN 5U /*!<@brief PORT pin number */ +#define BOARD_RMII0_RXER_PIN_MASK (1U << 5U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTA16 (number 46), U13[20]/RMII0_TXD0 + @{ */ +/* Routed pin properties */ +#define BOARD_RMII0_TXD0_PERIPHERAL ENET /*!<@brief Peripheral name */ +#define BOARD_RMII0_TXD0_SIGNAL RMII_TXD0 /*!<@brief Signal name */ +#define BOARD_RMII0_TXD0_PIN_NAME RMII0_TXD0 /*!<@brief Routed pin name */ +#define BOARD_RMII0_TXD0_LABEL "U13[20]/RMII0_TXD0" /*!<@brief Label */ +#define BOARD_RMII0_TXD0_NAME "RMII0_TXD0" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_RMII0_TXD0_PORT PORTA /*!<@brief PORT peripheral base pointer */ +#define BOARD_RMII0_TXD0_PIN 16U /*!<@brief PORT pin number */ +#define BOARD_RMII0_TXD0_PIN_MASK (1U << 16U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTA17 (number 47), U13[21]/RMII0_TXD1 + @{ */ +/* Routed pin properties */ +#define BOARD_RMII0_TXD1_PERIPHERAL ENET /*!<@brief Peripheral name */ +#define BOARD_RMII0_TXD1_SIGNAL RMII_TXD1 /*!<@brief Signal name */ +#define BOARD_RMII0_TXD1_PIN_NAME RMII0_TXD1 /*!<@brief Routed pin name */ +#define BOARD_RMII0_TXD1_LABEL "U13[21]/RMII0_TXD1" /*!<@brief Label */ +#define BOARD_RMII0_TXD1_NAME "RMII0_TXD1" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_RMII0_TXD1_PORT PORTA /*!<@brief PORT peripheral base pointer */ +#define BOARD_RMII0_TXD1_PIN 17U /*!<@brief PORT pin number */ +#define BOARD_RMII0_TXD1_PIN_MASK (1U << 17U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTA15 (number 45), U13[19]/RMII0_TXEN + @{ */ +/* Routed pin properties */ +#define BOARD_RMII0_TXEN_PERIPHERAL ENET /*!<@brief Peripheral name */ +#define BOARD_RMII0_TXEN_SIGNAL RMII_TXEN /*!<@brief Signal name */ +#define BOARD_RMII0_TXEN_PIN_NAME RMII0_TXEN /*!<@brief Routed pin name */ +#define BOARD_RMII0_TXEN_LABEL "U13[19]/RMII0_TXEN" /*!<@brief Label */ +#define BOARD_RMII0_TXEN_NAME "RMII0_TXEN" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_RMII0_TXEN_PORT PORTA /*!<@brief PORT peripheral base pointer */ +#define BOARD_RMII0_TXEN_PIN 15U /*!<@brief PORT pin number */ +#define BOARD_RMII0_TXEN_PIN_MASK (1U << 15U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTA14 (number 44), U13[15]/RMII0_CRS_DV + @{ */ +/* Routed pin properties */ +#define BOARD_RMII0_CRS_DV_PERIPHERAL ENET /*!<@brief Peripheral name */ +#define BOARD_RMII0_CRS_DV_SIGNAL RMII_CRS_DV /*!<@brief Signal name */ +#define BOARD_RMII0_CRS_DV_PIN_NAME RMII0_CRS_DV /*!<@brief Routed pin name */ +#define BOARD_RMII0_CRS_DV_LABEL "U13[15]/RMII0_CRS_DV" /*!<@brief Label */ +#define BOARD_RMII0_CRS_DV_NAME "RMII0_CRS_DV" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_RMII0_CRS_DV_PORT PORTA /*!<@brief PORT peripheral base pointer */ +#define BOARD_RMII0_CRS_DV_PIN 14U /*!<@brief PORT pin number */ +#define BOARD_RMII0_CRS_DV_PIN_MASK (1U << 14U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTA18 (number 50), U13[16]/RMII_RXCLK + @{ */ +/* Routed pin properties */ +#define BOARD_RMII_RXCLK_PERIPHERAL ENET /*!<@brief Peripheral name */ +#define BOARD_RMII_RXCLK_SIGNAL RMII_CLKIN /*!<@brief Signal name */ +#define BOARD_RMII_RXCLK_PIN_NAME EXTAL0 /*!<@brief Routed pin name */ +#define BOARD_RMII_RXCLK_LABEL "U13[16]/RMII_RXCLK" /*!<@brief Label */ +#define BOARD_RMII_RXCLK_NAME "RMII_RXCLK" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_RMII_RXCLK_PORT PORTA /*!<@brief PORT peripheral base pointer */ +#define BOARD_RMII_RXCLK_PIN 18U /*!<@brief PORT pin number */ +#define BOARD_RMII_RXCLK_PIN_MASK (1U << 18U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitENET(void); + +/*! @name PORTE0 (number 1), J15[P8]/SDHC0_D1 + @{ */ +/* Routed pin properties */ +#define BOARD_SDHC0_D1_PERIPHERAL SDHC /*!<@brief Peripheral name */ +#define BOARD_SDHC0_D1_SIGNAL DATA /*!<@brief Signal name */ +#define BOARD_SDHC0_D1_CHANNEL 1 /*!<@brief Signal channel */ +#define BOARD_SDHC0_D1_PIN_NAME SDHC0_D1 /*!<@brief Routed pin name */ +#define BOARD_SDHC0_D1_LABEL "J15[P8]/SDHC0_D1" /*!<@brief Label */ +#define BOARD_SDHC0_D1_NAME "SDHC0_D1" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_SDHC0_D1_PORT PORTE /*!<@brief PORT peripheral base pointer */ +#define BOARD_SDHC0_D1_PIN 0U /*!<@brief PORT pin number */ +#define BOARD_SDHC0_D1_PIN_MASK (1U << 0U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTE1 (number 2), J15[P7]/SDHC0_D0 + @{ */ +/* Routed pin properties */ +#define BOARD_SDHC0_D0_PERIPHERAL SDHC /*!<@brief Peripheral name */ +#define BOARD_SDHC0_D0_SIGNAL DATA /*!<@brief Signal name */ +#define BOARD_SDHC0_D0_CHANNEL 0 /*!<@brief Signal channel */ +#define BOARD_SDHC0_D0_PIN_NAME SDHC0_D0 /*!<@brief Routed pin name */ +#define BOARD_SDHC0_D0_LABEL "J15[P7]/SDHC0_D0" /*!<@brief Label */ +#define BOARD_SDHC0_D0_NAME "SDHC0_D0" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_SDHC0_D0_PORT PORTE /*!<@brief PORT peripheral base pointer */ +#define BOARD_SDHC0_D0_PIN 1U /*!<@brief PORT pin number */ +#define BOARD_SDHC0_D0_PIN_MASK (1U << 1U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTE2 (number 3), J15[P5]/SDHC0_DCLK + @{ */ +/* Routed pin properties */ +#define BOARD_SDHC0_DCLK_PERIPHERAL SDHC /*!<@brief Peripheral name */ +#define BOARD_SDHC0_DCLK_SIGNAL DCLK /*!<@brief Signal name */ +#define BOARD_SDHC0_DCLK_PIN_NAME SDHC0_DCLK /*!<@brief Routed pin name */ +#define BOARD_SDHC0_DCLK_LABEL "J15[P5]/SDHC0_DCLK" /*!<@brief Label */ +#define BOARD_SDHC0_DCLK_NAME "SDHC0_DCLK" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_SDHC0_DCLK_PORT PORTE /*!<@brief PORT peripheral base pointer */ +#define BOARD_SDHC0_DCLK_PIN 2U /*!<@brief PORT pin number */ +#define BOARD_SDHC0_DCLK_PIN_MASK (1U << 2U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTE3 (number 4), J15[P3]/SDHC0_CMD + @{ */ +/* Routed pin properties */ +#define BOARD_SDHC0_CMD_PERIPHERAL SDHC /*!<@brief Peripheral name */ +#define BOARD_SDHC0_CMD_SIGNAL CMD /*!<@brief Signal name */ +#define BOARD_SDHC0_CMD_PIN_NAME SDHC0_CMD /*!<@brief Routed pin name */ +#define BOARD_SDHC0_CMD_LABEL "J15[P3]/SDHC0_CMD" /*!<@brief Label */ +#define BOARD_SDHC0_CMD_NAME "SDHC0_CMD" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_SDHC0_CMD_PORT PORTE /*!<@brief PORT peripheral base pointer */ +#define BOARD_SDHC0_CMD_PIN 3U /*!<@brief PORT pin number */ +#define BOARD_SDHC0_CMD_PIN_MASK (1U << 3U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTE4 (number 5), J15[P2]/SDHC0_D3 + @{ */ +/* Routed pin properties */ +#define BOARD_SDHC0_D3_PERIPHERAL SDHC /*!<@brief Peripheral name */ +#define BOARD_SDHC0_D3_SIGNAL DATA /*!<@brief Signal name */ +#define BOARD_SDHC0_D3_CHANNEL 3 /*!<@brief Signal channel */ +#define BOARD_SDHC0_D3_PIN_NAME SDHC0_D3 /*!<@brief Routed pin name */ +#define BOARD_SDHC0_D3_LABEL "J15[P2]/SDHC0_D3" /*!<@brief Label */ +#define BOARD_SDHC0_D3_NAME "SDHC0_D3" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_SDHC0_D3_PORT PORTE /*!<@brief PORT peripheral base pointer */ +#define BOARD_SDHC0_D3_PIN 4U /*!<@brief PORT pin number */ +#define BOARD_SDHC0_D3_PIN_MASK (1U << 4U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTE5 (number 6), J15[P1]/SDHC0_D2 + @{ */ +/* Routed pin properties */ +#define BOARD_SDHC0_D2_PERIPHERAL SDHC /*!<@brief Peripheral name */ +#define BOARD_SDHC0_D2_SIGNAL DATA /*!<@brief Signal name */ +#define BOARD_SDHC0_D2_CHANNEL 2 /*!<@brief Signal channel */ +#define BOARD_SDHC0_D2_PIN_NAME SDHC0_D2 /*!<@brief Routed pin name */ +#define BOARD_SDHC0_D2_LABEL "J15[P1]/SDHC0_D2" /*!<@brief Label */ +#define BOARD_SDHC0_D2_NAME "SDHC0_D2" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_SDHC0_D2_PORT PORTE /*!<@brief PORT peripheral base pointer */ +#define BOARD_SDHC0_D2_PIN 5U /*!<@brief PORT pin number */ +#define BOARD_SDHC0_D2_PIN_MASK (1U << 5U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTE6 (number 7), J15[G1]/SD_CARD_DETECT + @{ */ +/* Routed pin properties */ +#define BOARD_SDHC_CD_PERIPHERAL GPIOE /*!<@brief Peripheral name */ +#define BOARD_SDHC_CD_SIGNAL GPIO /*!<@brief Signal name */ +#define BOARD_SDHC_CD_CHANNEL 6 /*!<@brief Signal channel */ +#define BOARD_SDHC_CD_PIN_NAME PTE6 /*!<@brief Routed pin name */ +#define BOARD_SDHC_CD_LABEL "J15[G1]/SD_CARD_DETECT" /*!<@brief Label */ +#define BOARD_SDHC_CD_NAME "SDHC_CD" /*!<@brief Identifier */ +#define BOARD_SDHC_CD_DIRECTION kPIN_MUX_DirectionInput /*!<@brief Direction */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_SDHC_CD_GPIO GPIOE /*!<@brief GPIO peripheral base pointer */ +#define BOARD_SDHC_CD_GPIO_PIN 6U /*!<@brief GPIO pin number */ +#define BOARD_SDHC_CD_GPIO_PIN_MASK (1U << 6U) /*!<@brief GPIO pin mask */ + +/* Symbols to be used with PORT driver */ +#define BOARD_SDHC_CD_PORT PORTE /*!<@brief PORT peripheral base pointer */ +#define BOARD_SDHC_CD_PIN 6U /*!<@brief PORT pin number */ +#define BOARD_SDHC_CD_PIN_MASK (1U << 6U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitSDHC(void); + +/*! @name USB0_DP (number 10), J22[3]/K64_MICRO_USB_DP + @{ */ +/* Routed pin properties */ +#define BOARD_USB_DP_PERIPHERAL USB0 /*!<@brief Peripheral name */ +#define BOARD_USB_DP_SIGNAL DP /*!<@brief Signal name */ +#define BOARD_USB_DP_PIN_NAME USB0_DP /*!<@brief Routed pin name */ +#define BOARD_USB_DP_LABEL "J22[3]/K64_MICRO_USB_DP" /*!<@brief Label */ +#define BOARD_USB_DP_NAME "USB_DP" /*!<@brief Identifier */ + /* @} */ + +/*! @name USB0_DM (number 11), J22[2]/K64_MICRO_USB_DN + @{ */ +/* Routed pin properties */ +#define BOARD_USB_DM_PERIPHERAL USB0 /*!<@brief Peripheral name */ +#define BOARD_USB_DM_SIGNAL DM /*!<@brief Signal name */ +#define BOARD_USB_DM_PIN_NAME USB0_DM /*!<@brief Routed pin name */ +#define BOARD_USB_DM_LABEL "J22[2]/K64_MICRO_USB_DN" /*!<@brief Label */ +#define BOARD_USB_DM_NAME "USB_DM" /*!<@brief Identifier */ + /* @} */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitUSB(void); + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ +#endif /* _PIN_MUX_H_ */ + +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/kinetis_k/boards/frdm_k64f/frdm_k64f.mex b/hw/bsp/kinetis_k/boards/frdm_k64f/frdm_k64f.mex new file mode 100644 index 000000000..28d1ea612 --- /dev/null +++ b/hw/bsp/kinetis_k/boards/frdm_k64f/frdm_k64f.mex @@ -0,0 +1,913 @@ + + + + MK64FN1M0xxx12 + MK64FN1M0VLL12 + FRDM-K64F + E1 + ksdk2_0 + + + + + + + true + true + false + true + false + + + + + + + + + 14.0.0 + + + + Configures pin routing and optionally pin electrical features. + + false + BOARD_ + core0 + true + + + + + true + + + + + + + Configures pin routing and optionally pin electrical features. + + true + BOARD_ + core0 + true + + + + + true + + + + + true + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Configures pin routing and optionally pin electrical features. + + true + BOARD_ + core0 + true + + + + + true + + + + + true + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Configures pin routing and optionally pin electrical features. + + true + BOARD_ + core0 + true + + + + + true + + + + + true + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Configures pin routing and optionally pin electrical features. + + false + BOARD_ + core0 + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + + + + + + + + + + + + + + + + + Configures pin routing and optionally pin electrical features. + + false + BOARD_ + core0 + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Configures pin routing and optionally pin electrical features. + + false + BOARD_ + core0 + true + + + + + true + + + + + true + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Configures pin routing and optionally pin electrical features. + + false + BOARD_ + core0 + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Configures pin routing and optionally pin electrical features. + + false + BOARD_ + core0 + true + + + + + true + + + + + true + + + + + + + + + + + + + + + + + 14.0.0 + + + + + + + + + true + + + + + INPUT + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + true + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + 0.0.0 + + + + + + + + true + + + + + + + + + 14.0.0 + + + + + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.0.0 + + + + + + + diff --git a/hw/bsp/kinetis_k/family.c b/hw/bsp/kinetis_k/family.c index b6e0e4093..38cfc45e3 100644 --- a/hw/bsp/kinetis_k/family.c +++ b/hw/bsp/kinetis_k/family.c @@ -23,7 +23,7 @@ * THE SOFTWARE. */ -#include "bsp/board.h" +#include "bsp/board_api.h" #include "board.h" #include "fsl_device_registers.h" #include "fsl_gpio.h" @@ -59,41 +59,28 @@ void board_init(void) { NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); #endif - // LED gpio_pin_config_t led_config = { kGPIO_DigitalOutput, 0 }; GPIO_PinInit(LED_PORT, LED_PIN, &led_config); board_led_write(false); #if defined(BUTTON_PORT) && defined(BUTTON_PIN) - // Button - CLOCK_EnableClock(BUTTON_PIN_CLOCK); - port_pin_config_t button_port = { - .pullSelect = kPORT_PullUp, - .mux = BUTTON_PIN_FUNCTION, - }; - PORT_SetPinConfig(BUTTON_PIN_PORT, BUTTON_PIN, &button_port); gpio_pin_config_t button_config = { kGPIO_DigitalInput, 0 }; GPIO_PinInit(BUTTON_PORT, BUTTON_PIN, &button_config); #endif -#if 0 - // UART - CLOCK_EnableClock(UART_PIN_CLOCK); - PORT_SetPinMux(UART_PIN_PORT, UART_PIN_RX, UART_PIN_FUNCTION); - PORT_SetPinMux(UART_PIN_PORT, UART_PIN_TX, UART_PIN_FUNCTION); - SIM->SOPT5 = ((SIM->SOPT5 & - (~(SIM_SOPT5_UART0TXSRC_MASK | SIM_SOPT5_UART0RXSRC_MASK))) - | SIM_SOPT5_UART0TXSRC(SOPT5_UART0TXSRC_UART_TX) - | SIM_SOPT5_UART0RXSRC(SOPT5_UART0RXSRC_UART_RX) - ); - - 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)); +#ifdef UART_DEV + const uart_config_t uart_config = { + .baudRate_Bps = 115200UL, + .parityMode = kUART_ParityDisabled, + .stopBitCount = kUART_OneStopBit, + .txFifoWatermark = 0U, + .rxFifoWatermark = 1U, + .idleType = kUART_IdleTypeStartBit, + .enableTx = true, + .enableRx = true + }; + UART_Init(UART_DEV, &uart_config, UART_CLOCK); #endif // USB @@ -119,13 +106,26 @@ uint32_t board_button_read(void) { int board_uart_read(uint8_t *buf, int len) { (void) buf; (void) len; +#ifdef UART_DEV + // Read blocking will block until there is data +// UART_ReadBlocking(UART_DEV, buf, len); +// return len; return 0; +#else + return 0; +#endif } int board_uart_write(void const *buf, int len) { (void) buf; (void) len; + +#ifdef UART_DEV + UART_WriteBlocking(UART_DEV, (uint8_t const*) buf, len); + return len; +#else return 0; +#endif } #if CFG_TUSB_OS == OPT_OS_NONE diff --git a/hw/bsp/kinetis_k/family.cmake b/hw/bsp/kinetis_k/family.cmake index 853316c3a..6d642c101 100644 --- a/hw/bsp/kinetis_k/family.cmake +++ b/hw/bsp/kinetis_k/family.cmake @@ -12,7 +12,7 @@ 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}/tools/cmake/toolchain/arm_${TOOLCHAIN}.cmake) +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS KINETIS_K CACHE INTERNAL "") From 3d3bf45102ded992fc10be09f3e9b9c981379ad1 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 24 Feb 2024 00:36:07 +0700 Subject: [PATCH 122/454] frdm k64f usb work well, add kinetis_k to ci cmake --- .github/workflows/cmake_arm.yml | 2 +- .../kinetis_k/boards/frdm_k64f/frdm_k64f.mex | 43 +++++++++++++++++-- hw/bsp/kinetis_k/family.c | 4 +- hw/bsp/kinetis_k/family.cmake | 1 + hw/bsp/kinetis_k/family.mk | 1 + src/portable/chipidea/ci_fs/ci_fs_kinetis.h | 6 +-- src/portable/chipidea/ci_fs/dcd_ci_fs.c | 8 ++++ src/portable/nxp/khci/dcd_khci.c | 14 ++---- 8 files changed, 60 insertions(+), 19 deletions(-) diff --git a/.github/workflows/cmake_arm.yml b/.github/workflows/cmake_arm.yml index f97645ad1..80ab1ea71 100644 --- a/.github/workflows/cmake_arm.yml +++ b/.github/workflows/cmake_arm.yml @@ -38,7 +38,7 @@ jobs: family: # Alphabetical order - 'imxrt' - - 'kinetis_kl' + - 'kinetis_k kinetis_kl' - 'lpc17 lpc18 lpc40 lpc43' - 'lpc54 lpc55' - 'mcx' diff --git a/hw/bsp/kinetis_k/boards/frdm_k64f/frdm_k64f.mex b/hw/bsp/kinetis_k/boards/frdm_k64f/frdm_k64f.mex index 28d1ea612..4a8c77f95 100644 --- a/hw/bsp/kinetis_k/boards/frdm_k64f/frdm_k64f.mex +++ b/hw/bsp/kinetis_k/boards/frdm_k64f/frdm_k64f.mex @@ -732,15 +732,27 @@ - + - true + true + + + + + 2.8.0 + + + + + + + 14.0.0 @@ -755,6 +767,31 @@ true + + + true + + + + + true + + + + + 0 + + + + + true + + + + + true + + @@ -789,7 +826,7 @@ - + diff --git a/hw/bsp/kinetis_k/family.c b/hw/bsp/kinetis_k/family.c index 38cfc45e3..6df29c1fc 100644 --- a/hw/bsp/kinetis_k/family.c +++ b/hw/bsp/kinetis_k/family.c @@ -30,6 +30,7 @@ #include "fsl_port.h" #include "fsl_clock.h" #include "fsl_uart.h" +#include "fsl_sysmpu.h" #include "board/clock_config.h" #include "board/pin_mux.h" @@ -50,6 +51,7 @@ void board_init(void) { BOARD_InitBootPins(); BOARD_BootClockRUN(); SystemCoreClockUpdate(); + SYSMPU_Enable(SYSMPU, 0); #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer @@ -84,7 +86,7 @@ void board_init(void) { #endif // USB - CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcPll0, CLOCK_GetFreq(kCLOCK_PllFllSelClk)); + // USB clock is configured in BOARD_BootClockRUN() } //--------------------------------------------------------------------+ diff --git a/hw/bsp/kinetis_k/family.cmake b/hw/bsp/kinetis_k/family.cmake index 6d642c101..e0b5fcfc8 100644 --- a/hw/bsp/kinetis_k/family.cmake +++ b/hw/bsp/kinetis_k/family.cmake @@ -40,6 +40,7 @@ function(add_board_target BOARD_TARGET) ${SDK_DIR}/drivers/gpio ${SDK_DIR}/drivers/port ${SDK_DIR}/drivers/smc + ${SDK_DIR}/drivers/sysmpu ${SDK_DIR}/drivers/uart ) diff --git a/hw/bsp/kinetis_k/family.mk b/hw/bsp/kinetis_k/family.mk index de352a6a9..995873eec 100644 --- a/hw/bsp/kinetis_k/family.mk +++ b/hw/bsp/kinetis_k/family.mk @@ -29,6 +29,7 @@ INC += \ $(TOP)/$(SDK_DIR)/drivers/gpio \ $(TOP)/$(SDK_DIR)/drivers/port \ $(TOP)/$(SDK_DIR)/drivers/smc \ + $(TOP)/$(SDK_DIR)/drivers/sysmpu \ $(TOP)/$(SDK_DIR)/drivers/uart \ SRC_S += ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_VARIANT}.S diff --git a/src/portable/chipidea/ci_fs/ci_fs_kinetis.h b/src/portable/chipidea/ci_fs/ci_fs_kinetis.h index cd21af1c7..31e14a546 100644 --- a/src/portable/chipidea/ci_fs/ci_fs_kinetis.h +++ b/src/portable/chipidea/ci_fs/ci_fs_kinetis.h @@ -36,14 +36,12 @@ #define CI_FS_REG(_port) ((ci_fs_regs_t*) USB0_BASE) #define CI_REG CI_FS_REG(0) -void dcd_int_enable(uint8_t rhport) -{ +void dcd_int_enable(uint8_t rhport) { (void) rhport; NVIC_EnableIRQ(USB0_IRQn); } -void dcd_int_disable(uint8_t rhport) -{ +void dcd_int_disable(uint8_t rhport) { (void) rhport; NVIC_DisableIRQ(USB0_IRQn); } diff --git a/src/portable/chipidea/ci_fs/dcd_ci_fs.c b/src/portable/chipidea/ci_fs/dcd_ci_fs.c index 9327e09d8..4b1d488b5 100644 --- a/src/portable/chipidea/ci_fs/dcd_ci_fs.c +++ b/src/portable/chipidea/ci_fs/dcd_ci_fs.c @@ -271,9 +271,17 @@ void dcd_init(uint8_t rhport) { (void) rhport; + // save crystal-less setting (recovery clock) + uint32_t clk_recover_irc_en = CI_REG->CLK_RECOVER_IRC_EN; + uint32_t clk_recover_ctrl = CI_REG->CLK_RECOVER_CTRL;; + CI_REG->USBTRC0 |= USB_USBTRC0_USBRESET_MASK; while (CI_REG->USBTRC0 & USB_USBTRC0_USBRESET_MASK); + // restore crystal-less setting + CI_REG->CLK_RECOVER_IRC_EN = clk_recover_irc_en; + CI_REG->CLK_RECOVER_CTRL |= clk_recover_ctrl; + tu_memclr(&_dcd, sizeof(_dcd)); CI_REG->USBTRC0 |= TU_BIT(6); /* software must set this bit to 1 */ CI_REG->BDT_PAGE1 = (uint8_t)((uintptr_t)_dcd.bdt >> 8); diff --git a/src/portable/nxp/khci/dcd_khci.c b/src/portable/nxp/khci/dcd_khci.c index 5a2f768b3..5d04a524a 100644 --- a/src/portable/nxp/khci/dcd_khci.c +++ b/src/portable/nxp/khci/dcd_khci.c @@ -269,22 +269,16 @@ void dcd_init(uint8_t rhport) { (void) rhport; -#if (CFG_TUSB_MCU == OPT_MCU_KINETIS_K) - uint32_t clk_recover_irc_en; - uint32_t clk_recover_ctrl; - - clk_recover_irc_en = KHCI->CLK_RECOVER_IRC_EN; - clk_recover_ctrl = KHCI->CLK_RECOVER_CTRL; + // save crystal-less setting (recovery clock) + uint32_t clk_recover_irc_en = KHCI->CLK_RECOVER_IRC_EN; + uint32_t clk_recover_ctrl = KHCI->CLK_RECOVER_CTRL; KHCI->USBTRC0 |= USB_USBTRC0_USBRESET_MASK; while (KHCI->USBTRC0 & USB_USBTRC0_USBRESET_MASK); + // restore crystal-less setting KHCI->CLK_RECOVER_IRC_EN = clk_recover_irc_en; KHCI->CLK_RECOVER_CTRL |= clk_recover_ctrl; -#else - KHCI->USBTRC0 |= USB_USBTRC0_USBRESET_MASK; - while (KHCI->USBTRC0 & USB_USBTRC0_USBRESET_MASK); -#endif tu_memclr(&_dcd, sizeof(_dcd)); KHCI->USBTRC0 |= TU_BIT(6); /* software must set this bit to 1 */ From 354998e96c4fafc8d55b73fced686fab1607c7ba Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 24 Feb 2024 00:41:46 +0700 Subject: [PATCH 123/454] update freertosconfig --- hw/bsp/kinetis_k/FreeRTOSConfig/FreeRTOSConfig.h | 6 +++--- hw/bsp/kinetis_k/family.cmake | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/hw/bsp/kinetis_k/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/kinetis_k/FreeRTOSConfig/FreeRTOSConfig.h index a46af1759..ed46508a4 100644 --- a/hw/bsp/kinetis_k/FreeRTOSConfig/FreeRTOSConfig.h +++ b/hw/bsp/kinetis_k/FreeRTOSConfig/FreeRTOSConfig.h @@ -73,8 +73,8 @@ #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 -#define configSUPPORT_STATIC_ALLOCATION 0 -#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 @@ -143,7 +143,7 @@ //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header -#define configPRIO_BITS 2 +#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: Sat, 24 Feb 2024 00:53:05 +0700 Subject: [PATCH 124/454] fix build with cpu without USB_CLK_RECOVER using old dcd_khci driver --- .idea/cmake.xml | 2 +- src/portable/nxp/khci/dcd_khci.c | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.idea/cmake.xml b/.idea/cmake.xml index dbb34aaab..ebc6a0570 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -59,7 +59,7 @@ - + diff --git a/src/portable/nxp/khci/dcd_khci.c b/src/portable/nxp/khci/dcd_khci.c index 5d04a524a..3419c2565 100644 --- a/src/portable/nxp/khci/dcd_khci.c +++ b/src/portable/nxp/khci/dcd_khci.c @@ -270,15 +270,19 @@ void dcd_init(uint8_t rhport) (void) rhport; // save crystal-less setting (recovery clock) + #ifdef USB_CLK_RECOVER_IRC_EN_IRC_EN uint32_t clk_recover_irc_en = KHCI->CLK_RECOVER_IRC_EN; uint32_t clk_recover_ctrl = KHCI->CLK_RECOVER_CTRL; + #endif KHCI->USBTRC0 |= USB_USBTRC0_USBRESET_MASK; while (KHCI->USBTRC0 & USB_USBTRC0_USBRESET_MASK); // restore crystal-less setting + #ifdef USB_CLK_RECOVER_IRC_EN_IRC_EN KHCI->CLK_RECOVER_IRC_EN = clk_recover_irc_en; KHCI->CLK_RECOVER_CTRL |= clk_recover_ctrl; + #endif tu_memclr(&_dcd, sizeof(_dcd)); KHCI->USBTRC0 |= TU_BIT(6); /* software must set this bit to 1 */ From a52b4647ec20414bbfde986c13a18598ffd426d6 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 24 Feb 2024 17:18:30 +0700 Subject: [PATCH 125/454] only save/restore CLK_RECOVER_IRC_EN/CTRL if FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED is defined to 1 --- src/portable/chipidea/ci_fs/dcd_ci_fs.c | 10 +++++++--- src/portable/nxp/khci/dcd_khci.c | 8 ++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/portable/chipidea/ci_fs/dcd_ci_fs.c b/src/portable/chipidea/ci_fs/dcd_ci_fs.c index 4b1d488b5..a68ecf8c9 100644 --- a/src/portable/chipidea/ci_fs/dcd_ci_fs.c +++ b/src/portable/chipidea/ci_fs/dcd_ci_fs.c @@ -271,16 +271,20 @@ void dcd_init(uint8_t rhport) { (void) rhport; - // save crystal-less setting (recovery clock) + // save crystal-less setting (if available) + #if defined(FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED) && FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED == 1 uint32_t clk_recover_irc_en = CI_REG->CLK_RECOVER_IRC_EN; - uint32_t clk_recover_ctrl = CI_REG->CLK_RECOVER_CTRL;; + uint32_t clk_recover_ctrl = CI_REG->CLK_RECOVER_CTRL; + #endif CI_REG->USBTRC0 |= USB_USBTRC0_USBRESET_MASK; while (CI_REG->USBTRC0 & USB_USBTRC0_USBRESET_MASK); - // restore crystal-less setting + // restore crystal-less setting (if available) + #if defined(FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED) && FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED == 1 CI_REG->CLK_RECOVER_IRC_EN = clk_recover_irc_en; CI_REG->CLK_RECOVER_CTRL |= clk_recover_ctrl; + #endif tu_memclr(&_dcd, sizeof(_dcd)); CI_REG->USBTRC0 |= TU_BIT(6); /* software must set this bit to 1 */ diff --git a/src/portable/nxp/khci/dcd_khci.c b/src/portable/nxp/khci/dcd_khci.c index 3419c2565..dc71117b3 100644 --- a/src/portable/nxp/khci/dcd_khci.c +++ b/src/portable/nxp/khci/dcd_khci.c @@ -269,8 +269,8 @@ void dcd_init(uint8_t rhport) { (void) rhport; - // save crystal-less setting (recovery clock) - #ifdef USB_CLK_RECOVER_IRC_EN_IRC_EN + // save crystal-less setting (if available) + #if defined(FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED) && FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED == 1 uint32_t clk_recover_irc_en = KHCI->CLK_RECOVER_IRC_EN; uint32_t clk_recover_ctrl = KHCI->CLK_RECOVER_CTRL; #endif @@ -278,8 +278,8 @@ void dcd_init(uint8_t rhport) KHCI->USBTRC0 |= USB_USBTRC0_USBRESET_MASK; while (KHCI->USBTRC0 & USB_USBTRC0_USBRESET_MASK); - // restore crystal-less setting - #ifdef USB_CLK_RECOVER_IRC_EN_IRC_EN + // restore crystal-less setting (if available) + #if defined(FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED) && FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED == 1 KHCI->CLK_RECOVER_IRC_EN = clk_recover_irc_en; KHCI->CLK_RECOVER_CTRL |= clk_recover_ctrl; #endif From 23450d4f6bba4b5b92e242a61684dfcf171e6cbe Mon Sep 17 00:00:00 2001 From: IngHK Date: Sat, 24 Feb 2024 15:51:02 +0100 Subject: [PATCH 126/454] fixed compiler warning src/tusb.c --- src/tusb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tusb.c b/src/tusb.c index 7943ea5ef..3ef380c83 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -477,7 +477,7 @@ void tu_print_mem(void const *buf, uint32_t count, uint8_t indent) uint8_t const *buf8 = (uint8_t const *) buf; char format[] = "%00X"; - format[2] += 2*size; + format[2] += (uint8_t) (2*size); // 1 byte = 2 hex digits const uint8_t item_per_line = 16 / size; From 2a21b6980b8efc87adb44f20a60a5f2ffda79518 Mon Sep 17 00:00:00 2001 From: Jerry Palacios Date: Sat, 24 Feb 2024 17:16:32 -0600 Subject: [PATCH 127/454] MCX family pointing to updated mcux-sdk repository --- tools/get_deps.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/get_deps.py b/tools/get_deps.py index 2a14c6123..a502c901f 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -50,9 +50,9 @@ deps_optional = { '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/wavenumber-eng/mcux-sdk.git', - 'main', - 'kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcxn mcxa imxrt'], + 'hw/mcu/nxp/mcux-sdk': ['https://github.com/hathach/mcux-sdk.git', + '144f1eb7ea8c06512e12f12b27383601c0272410', + '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'], @@ -175,7 +175,7 @@ deps_optional = { 'ch32f20x'], 'lib/CMSIS_5': ['https://github.com/ARM-software/CMSIS_5.git', '20285262657d1b482d132d20d755c8c330d55c1f', - 'imxrt kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcxn mcxa mm32 msp432e4 nrf ra saml2x' + 'imxrt kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx mm32 msp432e4 nrf ra saml2x' 'stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h5' 'stm32h7 stm32l0 stm32l1 stm32l4 stm32l5 stm32u5 stm32wb'], 'lib/sct_neopixel': ['https://github.com/gsteiert/sct_neopixel.git', From 5ce7b147117826dd75c2d7b347df80b0177e7252 Mon Sep 17 00:00:00 2001 From: Tommie Gannert Date: Mon, 26 Feb 2024 11:41:50 +0100 Subject: [PATCH 128/454] 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_ */ From 473d400cfde768e26fe8644bab3d655c81777b64 Mon Sep 17 00:00:00 2001 From: Taylor Yu Date: Sun, 25 Feb 2024 11:12:24 -0600 Subject: [PATCH 129/454] work around possible RP2040 erratum RP2040 device controller does not seem to clear pending transactions configured in EP0 buffer controls when the host aborts a control transfer. This causes assertion failures, including when a buffer AVAILABLE flag set for a previous transfer causes an unexpected transaction completion. --- src/portable/raspberrypi/rp2040/dcd_rp2040.c | 31 ++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index e8cee73fd..51174f709 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -217,6 +217,18 @@ static void __tusb_irq_path_func(hw_handle_buff_status)(void) TU_ATTR_ALWAYS_INLINE static inline void reset_ep0_pid(void) { + // Abort any transactions from a prior control transfer, because + // receiving SETUP doesn't reset buffer control state. This works around + // a possible USB hardware erratum. + + // With this workaround a race window still exists, but smaller. + // ABORT flag is unusable prior to hardware B2 (RP2040-E2), so a larger + // race window exists for B1 and earlier. + if (rp2040_chip_version() >= 2) { + usb_hw_set->abort = 0x3; + while ((usb_hw->abort_done & 0x3) != 0x3) + ; + } // If we have finished this transfer on EP0 set pid back to 1 for next // setup transfer. Also clear a stall in case uint8_t addrs[] = {0x0, 0x80}; @@ -224,6 +236,25 @@ TU_ATTR_ALWAYS_INLINE static inline void reset_ep0_pid(void) { struct hw_endpoint *ep = hw_endpoint_get_by_addr(addrs[i]); ep->next_pid = 1u; + // Reset the buffer control now to minimize race conditions + _hw_endpoint_buffer_control_set_value32(ep, USB_BUF_CTRL_DATA1_PID | USB_BUF_CTRL_SEL); + // Explicit delay, because the one in + // _hw_endpoint_buffer_control_set_value32 is only to set AVAILABLE + __asm volatile ( + "b 1f\n" + "1: b 1f\n" + "1: b 1f\n" + "1: b 1f\n" + "1: b 1f\n" + "1: b 1f\n" + "1:\n" + : : : "memory"); + // Make sure local ep state matches peripheral + hw_endpoint_reset_transfer(ep); + } + if (rp2040_chip_version() >= 2) { + usb_hw_clear->abort = 0x3; + usb_hw_clear->abort_done = 0x3; } } From 4ed02ae5f97b57bd442521234b81a381c507d3a1 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 1 Mar 2024 17:34:14 +0700 Subject: [PATCH 130/454] reformat code hid_host.c - fix ceedling with ruby 3.1 - allow overwrite CMAKE_C_COMPILER/CMAKE_CXX_COMPILER from command line --- .../cmake/toolchain/arm_gcc.cmake | 12 +- src/class/hid/hid_host.c | 517 ++++++++---------- test/unit-test/project.yml | 13 +- 3 files changed, 230 insertions(+), 312 deletions(-) diff --git a/examples/build_system/cmake/toolchain/arm_gcc.cmake b/examples/build_system/cmake/toolchain/arm_gcc.cmake index 7680d75ab..d3fd5b557 100644 --- a/examples/build_system/cmake/toolchain/arm_gcc.cmake +++ b/examples/build_system/cmake/toolchain/arm_gcc.cmake @@ -1,8 +1,14 @@ set(CMAKE_SYSTEM_NAME Generic) -set(CMAKE_C_COMPILER "arm-none-eabi-gcc") -set(CMAKE_CXX_COMPILER "arm-none-eabi-g++") -set(CMAKE_ASM_COMPILER "arm-none-eabi-gcc") +if (NOT DEFINED CMAKE_C_COMPILER) + set(CMAKE_C_COMPILER "arm-none-eabi-gcc") +endif () + +if (NOT DEFINED CMAKE_CXX_COMPILER) + set(CMAKE_CXX_COMPILER "arm-none-eabi-g++") +endif () + +set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) set(CMAKE_SIZE "arm-none-eabi-size" CACHE FILEPATH "") set(CMAKE_OBJCOPY "arm-none-eabi-objcopy" CACHE FILEPATH "") diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 709fa3dd8..21aee531a 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -39,12 +39,11 @@ #endif #define TU_LOG_DRV(...) TU_LOG(CFG_TUH_HID_LOG_LEVEL, __VA_ARGS__) + //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ - -typedef struct -{ +typedef struct { uint8_t daddr; uint8_t itf_num; @@ -55,7 +54,7 @@ typedef struct uint8_t itf_protocol; // None, Keyboard, Mouse uint8_t protocol_mode; // Boot (0) or Report protocol (1) - uint8_t report_desc_type; + uint8_t report_desc_type; uint16_t report_desc_len; uint16_t epin_size; @@ -73,79 +72,57 @@ tu_static uint8_t _hidh_default_protocol = HID_PROTOCOL_BOOT; //--------------------------------------------------------------------+ // Helper //--------------------------------------------------------------------+ - -TU_ATTR_ALWAYS_INLINE static inline -hidh_interface_t* get_hid_itf(uint8_t daddr, uint8_t idx) -{ +TU_ATTR_ALWAYS_INLINE static inline hidh_interface_t* get_hid_itf(uint8_t daddr, uint8_t idx) { TU_ASSERT(daddr > 0 && idx < CFG_TUH_HID, NULL); hidh_interface_t* p_hid = &_hidh_itf[idx]; return (p_hid->daddr == daddr) ? p_hid : NULL; } // Get instance ID by endpoint address -static uint8_t get_idx_by_epaddr(uint8_t daddr, uint8_t ep_addr) -{ - for ( uint8_t idx = 0; idx < CFG_TUH_HID; idx++ ) - { - hidh_interface_t const * p_hid = &_hidh_itf[idx]; - - if ( p_hid->daddr == daddr && - (p_hid->ep_in == ep_addr || p_hid->ep_out == ep_addr) ) - { +static uint8_t get_idx_by_epaddr(uint8_t daddr, uint8_t ep_addr) { + for (uint8_t idx = 0; idx < CFG_TUH_HID; idx++) { + hidh_interface_t const* p_hid = &_hidh_itf[idx]; + if (p_hid->daddr == daddr && + (p_hid->ep_in == ep_addr || p_hid->ep_out == ep_addr)) { return idx; } } - return TUSB_INDEX_INVALID_8; } -static hidh_interface_t* find_new_itf(void) -{ - for(uint8_t i=0; imounted; } -bool tuh_hid_itf_get_info(uint8_t daddr, uint8_t idx, tuh_itf_info_t* info) -{ +bool tuh_hid_itf_get_info(uint8_t daddr, uint8_t idx, tuh_itf_info_t* info) { hidh_interface_t* p_hid = get_hid_itf(daddr, idx); TU_VERIFY(p_hid && info); @@ -153,34 +130,30 @@ bool tuh_hid_itf_get_info(uint8_t daddr, uint8_t idx, tuh_itf_info_t* info) // re-construct descriptor tusb_desc_interface_t* desc = &info->desc; - desc->bLength = sizeof(tusb_desc_interface_t); - desc->bDescriptorType = TUSB_DESC_INTERFACE; + desc->bLength = sizeof(tusb_desc_interface_t); + desc->bDescriptorType = TUSB_DESC_INTERFACE; - desc->bInterfaceNumber = p_hid->itf_num; - desc->bAlternateSetting = 0; - desc->bNumEndpoints = (uint8_t) ((p_hid->ep_in ? 1u : 0u) + (p_hid->ep_out ? 1u : 0u)); - desc->bInterfaceClass = TUSB_CLASS_HID; + desc->bInterfaceNumber = p_hid->itf_num; + desc->bAlternateSetting = 0; + desc->bNumEndpoints = (uint8_t) ((p_hid->ep_in ? 1u : 0u) + (p_hid->ep_out ? 1u : 0u)); + desc->bInterfaceClass = TUSB_CLASS_HID; desc->bInterfaceSubClass = (p_hid->itf_protocol ? HID_SUBCLASS_BOOT : HID_SUBCLASS_NONE); desc->bInterfaceProtocol = p_hid->itf_protocol; - desc->iInterface = 0; // not used yet + desc->iInterface = 0; // not used yet return true; } -uint8_t tuh_hid_itf_get_index(uint8_t daddr, uint8_t itf_num) -{ - for ( uint8_t idx = 0; idx < CFG_TUH_HID; idx++ ) - { - hidh_interface_t const * p_hid = &_hidh_itf[idx]; - - if ( p_hid->daddr == daddr && p_hid->itf_num == itf_num) return idx; +uint8_t tuh_hid_itf_get_index(uint8_t daddr, uint8_t itf_num) { + for (uint8_t idx = 0; idx < CFG_TUH_HID; idx++) { + hidh_interface_t const* p_hid = &_hidh_itf[idx]; + if (p_hid->daddr == daddr && p_hid->itf_num == itf_num) return idx; } return TUSB_INDEX_INVALID_8; } -uint8_t tuh_hid_interface_protocol(uint8_t daddr, uint8_t idx) -{ +uint8_t tuh_hid_interface_protocol(uint8_t daddr, uint8_t idx) { hidh_interface_t* p_hid = get_hid_itf(daddr, idx); return p_hid ? p_hid->itf_protocol : 0; } @@ -188,29 +161,24 @@ uint8_t tuh_hid_interface_protocol(uint8_t daddr, uint8_t idx) //--------------------------------------------------------------------+ // Control Endpoint API //--------------------------------------------------------------------+ - -uint8_t tuh_hid_get_protocol(uint8_t daddr, uint8_t idx) -{ +uint8_t tuh_hid_get_protocol(uint8_t daddr, uint8_t idx) { hidh_interface_t* p_hid = get_hid_itf(daddr, idx); return p_hid ? p_hid->protocol_mode : 0; } -static void set_protocol_complete(tuh_xfer_t* xfer) -{ +static void set_protocol_complete(tuh_xfer_t* xfer) { uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); - uint8_t const daddr = xfer->daddr; - uint8_t const idx = tuh_hid_itf_get_index(daddr, itf_num); + uint8_t const daddr = xfer->daddr; + uint8_t const idx = tuh_hid_itf_get_index(daddr, itf_num); hidh_interface_t* p_hid = get_hid_itf(daddr, idx); - TU_VERIFY(p_hid, ); + TU_VERIFY(p_hid,); - if (XFER_RESULT_SUCCESS == xfer->result) - { + if (XFER_RESULT_SUCCESS == xfer->result) { p_hid->protocol_mode = (uint8_t) tu_le16toh(xfer->setup->wValue); } - if (tuh_hid_set_protocol_complete_cb) - { + if (tuh_hid_set_protocol_complete_cb) { tuh_hid_set_protocol_complete_cb(daddr, idx, p_hid->protocol_mode); } } @@ -219,123 +187,109 @@ void tuh_hid_set_default_protocol(uint8_t protocol) { _hidh_default_protocol = protocol; } -static bool _hidh_set_protocol(uint8_t daddr, uint8_t itf_num, uint8_t protocol, tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ +static bool _hidh_set_protocol(uint8_t daddr, uint8_t itf_num, uint8_t protocol, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { TU_LOG_DRV("HID Set Protocol = %d\r\n", protocol); - tusb_control_request_t const request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_OUT - }, - .bRequest = HID_REQ_CONTROL_SET_PROTOCOL, - .wValue = protocol, - .wIndex = itf_num, - .wLength = 0 + tusb_control_request_t const request = { + .bmRequestType_bit = { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_OUT + }, + .bRequest = HID_REQ_CONTROL_SET_PROTOCOL, + .wValue = protocol, + .wIndex = itf_num, + .wLength = 0 }; - tuh_xfer_t xfer = - { - .daddr = daddr, - .ep_addr = 0, - .setup = &request, - .buffer = NULL, - .complete_cb = complete_cb, - .user_data = user_data + tuh_xfer_t xfer = { + .daddr = daddr, + .ep_addr = 0, + .setup = &request, + .buffer = NULL, + .complete_cb = complete_cb, + .user_data = user_data }; return tuh_control_xfer(&xfer); } -bool tuh_hid_set_protocol(uint8_t daddr, uint8_t idx, uint8_t protocol) -{ +bool tuh_hid_set_protocol(uint8_t daddr, uint8_t idx, uint8_t protocol) { hidh_interface_t* p_hid = get_hid_itf(daddr, idx); TU_VERIFY(p_hid && p_hid->itf_protocol != HID_ITF_PROTOCOL_NONE); return _hidh_set_protocol(daddr, p_hid->itf_num, protocol, set_protocol_complete, 0); } -static void set_report_complete(tuh_xfer_t* xfer) -{ +static void set_report_complete(tuh_xfer_t* xfer) { TU_LOG_DRV("HID Set Report complete\r\n"); - if (tuh_hid_set_report_complete_cb) - { + if (tuh_hid_set_report_complete_cb) { uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); - uint8_t const idx = tuh_hid_itf_get_index(xfer->daddr, itf_num); + uint8_t const idx = tuh_hid_itf_get_index(xfer->daddr, itf_num); uint8_t const report_type = tu_u16_high(xfer->setup->wValue); - uint8_t const report_id = tu_u16_low(xfer->setup->wValue); + uint8_t const report_id = tu_u16_low(xfer->setup->wValue); tuh_hid_set_report_complete_cb(xfer->daddr, idx, report_id, report_type, (xfer->result == XFER_RESULT_SUCCESS) ? xfer->setup->wLength : 0); } } -bool tuh_hid_set_report(uint8_t daddr, uint8_t idx, uint8_t report_id, uint8_t report_type, void* report, uint16_t len) -{ +bool tuh_hid_set_report(uint8_t daddr, uint8_t idx, uint8_t report_id, uint8_t report_type, void* report, uint16_t len) { hidh_interface_t* p_hid = get_hid_itf(daddr, idx); TU_VERIFY(p_hid); - TU_LOG_DRV("HID Set Report: id = %u, type = %u, len = %u\r\n", report_id, report_type, len); - tusb_control_request_t const request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_OUT - }, - .bRequest = HID_REQ_CONTROL_SET_REPORT, - .wValue = tu_htole16(tu_u16(report_type, report_id)), - .wIndex = tu_htole16((uint16_t)p_hid->itf_num), - .wLength = len + tusb_control_request_t const request = { + .bmRequestType_bit = { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_OUT + }, + .bRequest = HID_REQ_CONTROL_SET_REPORT, + .wValue = tu_htole16(tu_u16(report_type, report_id)), + .wIndex = tu_htole16((uint16_t) p_hid->itf_num), + .wLength = len }; - tuh_xfer_t xfer = - { - .daddr = daddr, - .ep_addr = 0, - .setup = &request, - .buffer = report, - .complete_cb = set_report_complete, - .user_data = 0 + tuh_xfer_t xfer = { + .daddr = daddr, + .ep_addr = 0, + .setup = &request, + .buffer = report, + .complete_cb = set_report_complete, + .user_data = 0 }; return tuh_control_xfer(&xfer); } -static bool _hidh_set_idle(uint8_t daddr, uint8_t itf_num, uint16_t idle_rate, tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ +static bool _hidh_set_idle(uint8_t daddr, uint8_t itf_num, uint16_t idle_rate, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { // SET IDLE request, device can stall if not support this request TU_LOG_DRV("HID Set Idle \r\n"); - tusb_control_request_t const request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_OUT - }, - .bRequest = HID_REQ_CONTROL_SET_IDLE, - .wValue = tu_htole16(idle_rate), - .wIndex = tu_htole16((uint16_t)itf_num), - .wLength = 0 + tusb_control_request_t const request = { + .bmRequestType_bit = { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_OUT + }, + .bRequest = HID_REQ_CONTROL_SET_IDLE, + .wValue = tu_htole16(idle_rate), + .wIndex = tu_htole16((uint16_t) itf_num), + .wLength = 0 }; - tuh_xfer_t xfer = - { - .daddr = daddr, - .ep_addr = 0, - .setup = &request, - .buffer = NULL, - .complete_cb = complete_cb, - .user_data = user_data + tuh_xfer_t xfer = { + .daddr = daddr, + .ep_addr = 0, + .setup = &request, + .buffer = NULL, + .complete_cb = complete_cb, + .user_data = user_data }; return tuh_control_xfer(&xfer); @@ -346,24 +300,20 @@ static bool _hidh_set_idle(uint8_t daddr, uint8_t itf_num, uint16_t idle_rate, t //--------------------------------------------------------------------+ // Check if HID interface is ready to receive report -bool tuh_hid_receive_ready(uint8_t dev_addr, uint8_t idx) -{ +bool tuh_hid_receive_ready(uint8_t dev_addr, uint8_t idx) { hidh_interface_t* p_hid = get_hid_itf(dev_addr, idx); TU_VERIFY(p_hid); - return !usbh_edpt_busy(dev_addr, p_hid->ep_in); } -bool tuh_hid_receive_report(uint8_t daddr, uint8_t idx) -{ +bool tuh_hid_receive_report(uint8_t daddr, uint8_t idx) { hidh_interface_t* p_hid = get_hid_itf(daddr, idx); TU_VERIFY(p_hid); // claim endpoint - TU_VERIFY( usbh_edpt_claim(daddr, p_hid->ep_in) ); + TU_VERIFY(usbh_edpt_claim(daddr, p_hid->ep_in)); - if ( !usbh_edpt_xfer(daddr, p_hid->ep_in, p_hid->epin_buf, p_hid->epin_size) ) - { + if (!usbh_edpt_xfer(daddr, p_hid->ep_in, p_hid->epin_buf, p_hid->epin_size)) { usbh_edpt_release(daddr, p_hid->ep_in); return false; } @@ -371,43 +321,34 @@ bool tuh_hid_receive_report(uint8_t daddr, uint8_t idx) return true; } -bool tuh_hid_send_ready(uint8_t dev_addr, uint8_t idx) -{ +bool tuh_hid_send_ready(uint8_t dev_addr, uint8_t idx) { hidh_interface_t* p_hid = get_hid_itf(dev_addr, idx); TU_VERIFY(p_hid); - return !usbh_edpt_busy(dev_addr, p_hid->ep_out); } -bool tuh_hid_send_report(uint8_t daddr, uint8_t idx, uint8_t report_id, const void* report, uint16_t len) -{ +bool tuh_hid_send_report(uint8_t daddr, uint8_t idx, uint8_t report_id, const void* report, uint16_t len) { TU_LOG_DRV("HID Send Report %d\r\n", report_id); hidh_interface_t* p_hid = get_hid_itf(daddr, idx); TU_VERIFY(p_hid); - if (p_hid->ep_out == 0) - { + if (p_hid->ep_out == 0) { // This HID does not have an out endpoint (other than control) return false; - } - else if (len > CFG_TUH_HID_EPOUT_BUFSIZE || - (report_id != 0 && len > (CFG_TUH_HID_EPOUT_BUFSIZE - 1))) - { + } else if (len > CFG_TUH_HID_EPOUT_BUFSIZE || + (report_id != 0 && len > (CFG_TUH_HID_EPOUT_BUFSIZE - 1))) { // ep_out buffer is not large enough to hold contents return false; } // claim endpoint - TU_VERIFY( usbh_edpt_claim(daddr, p_hid->ep_out) ); + TU_VERIFY(usbh_edpt_claim(daddr, p_hid->ep_out)); - if (report_id == 0) - { + if (report_id == 0) { // No report ID in transmission memcpy(&p_hid->epout_buf[0], report, len); - } - else - { + } else { p_hid->epout_buf[0] = report_id; memcpy(&p_hid->epout_buf[1], report, len); ++len; // 1 more byte for report_id @@ -415,8 +356,7 @@ bool tuh_hid_send_report(uint8_t daddr, uint8_t idx, uint8_t report_id, const vo TU_LOG3_MEM(p_hid->epout_buf, len, 2); - if ( !usbh_edpt_xfer(daddr, p_hid->ep_out, p_hid->epout_buf, len) ) - { + if (!usbh_edpt_xfer(daddr, p_hid->ep_out, p_hid->epout_buf, len)) { usbh_edpt_release(daddr, p_hid->ep_out); return false; } @@ -427,13 +367,11 @@ bool tuh_hid_send_report(uint8_t daddr, uint8_t idx, uint8_t report_id, const vo //--------------------------------------------------------------------+ // USBH API //--------------------------------------------------------------------+ -void hidh_init(void) -{ +void hidh_init(void) { tu_memclr(_hidh_itf, sizeof(_hidh_itf)); } -bool hidh_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) -{ +bool hidh_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void) result; uint8_t const dir = tu_edpt_dir(ep_addr); @@ -442,28 +380,25 @@ bool hidh_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t result, uint32_t hidh_interface_t* p_hid = get_hid_itf(daddr, idx); TU_VERIFY(p_hid); - if ( dir == TUSB_DIR_IN ) - { + if (dir == TUSB_DIR_IN) { TU_LOG_DRV(" Get Report callback (%u, %u)\r\n", daddr, idx); TU_LOG3_MEM(p_hid->epin_buf, xferred_bytes, 2); tuh_hid_report_received_cb(daddr, idx, p_hid->epin_buf, (uint16_t) xferred_bytes); - }else - { - if (tuh_hid_report_sent_cb) tuh_hid_report_sent_cb(daddr, idx, p_hid->epout_buf, (uint16_t) xferred_bytes); + } else { + if (tuh_hid_report_sent_cb) { + tuh_hid_report_sent_cb(daddr, idx, p_hid->epout_buf, (uint16_t) xferred_bytes); + } } return true; } -void hidh_close(uint8_t daddr) -{ - for(uint8_t i=0; idaddr == daddr) - { + if (p_hid->daddr == daddr) { TU_LOG_DRV(" HIDh close addr = %u index = %u\r\n", daddr, i); - if(tuh_hid_umount_cb) tuh_hid_umount_cb(daddr, i); + if (tuh_hid_umount_cb) tuh_hid_umount_cb(daddr, i); p_hid->daddr = 0; p_hid->mounted = false; } @@ -474,25 +409,22 @@ void hidh_close(uint8_t daddr) // Enumeration //--------------------------------------------------------------------+ -bool hidh_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const *desc_itf, uint16_t max_len) -{ +bool hidh_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const* desc_itf, uint16_t max_len) { (void) rhport; (void) max_len; TU_VERIFY(TUSB_CLASS_HID == desc_itf->bInterfaceClass); - TU_LOG_DRV("[%u] HID opening Interface %u\r\n", daddr, desc_itf->bInterfaceNumber); // 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)); TU_ASSERT(max_len >= drv_len); - - uint8_t const *p_desc = (uint8_t const *) desc_itf; + uint8_t const* p_desc = (uint8_t const*) desc_itf; //------------- HID descriptor -------------// p_desc = tu_desc_next(p_desc); - tusb_hid_descriptor_hid_t const *desc_hid = (tusb_hid_descriptor_hid_t const *) p_desc; + tusb_hid_descriptor_hid_t const* desc_hid = (tusb_hid_descriptor_hid_t const*) p_desc; TU_ASSERT(HID_DESC_TYPE_HID == desc_hid->bDescriptorType); hidh_interface_t* p_hid = find_new_itf(); @@ -501,38 +433,33 @@ bool hidh_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const *desc_ //------------- Endpoint Descriptors -------------// p_desc = tu_desc_next(p_desc); - 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; - for(int i = 0; i < desc_itf->bNumEndpoints; i++) - { + for (int i = 0; i < desc_itf->bNumEndpoints; i++) { TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType); - TU_ASSERT( tuh_edpt_open(daddr, desc_ep) ); + TU_ASSERT(tuh_edpt_open(daddr, desc_ep)); - if(tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) - { - p_hid->ep_in = desc_ep->bEndpointAddress; + if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { + p_hid->ep_in = desc_ep->bEndpointAddress; p_hid->epin_size = tu_edpt_packet_size(desc_ep); - } - else - { - p_hid->ep_out = desc_ep->bEndpointAddress; + } else { + p_hid->ep_out = desc_ep->bEndpointAddress; p_hid->epout_size = tu_edpt_packet_size(desc_ep); } p_desc = tu_desc_next(p_desc); - desc_ep = (tusb_desc_endpoint_t const *) p_desc; + desc_ep = (tusb_desc_endpoint_t const*) p_desc; } - p_hid->itf_num = desc_itf->bInterfaceNumber; + p_hid->itf_num = desc_itf->bInterfaceNumber; // Assume bNumDescriptors = 1 p_hid->report_desc_type = desc_hid->bReportType; - p_hid->report_desc_len = tu_unaligned_read16(&desc_hid->wReportLength); + p_hid->report_desc_len = tu_unaligned_read16(&desc_hid->wReportLength); // Per HID Specs: default is Report protocol, though we will force Boot protocol when set_config p_hid->protocol_mode = _hidh_default_protocol; - if ( HID_SUBCLASS_BOOT == desc_itf->bInterfaceSubClass ) - { + if (HID_SUBCLASS_BOOT == desc_itf->bInterfaceSubClass) { p_hid->itf_protocol = desc_itf->bInterfaceProtocol; } @@ -553,15 +480,14 @@ enum { static void config_driver_mount_complete(uint8_t daddr, uint8_t idx, uint8_t const* desc_report, uint16_t desc_len); static void process_set_config(tuh_xfer_t* xfer); -bool hidh_set_config(uint8_t daddr, uint8_t itf_num) -{ +bool hidh_set_config(uint8_t daddr, uint8_t itf_num) { tusb_control_request_t request; request.wIndex = tu_htole16((uint16_t) itf_num); tuh_xfer_t xfer; - xfer.daddr = daddr; - xfer.result = XFER_RESULT_SUCCESS; - xfer.setup = &request; + xfer.daddr = daddr; + xfer.result = XFER_RESULT_SUCCESS; + xfer.setup = &request; xfer.user_data = CONFG_SET_IDLE; // fake request to kick-off the set config process @@ -570,71 +496,67 @@ bool hidh_set_config(uint8_t daddr, uint8_t itf_num) return true; } -static void process_set_config(tuh_xfer_t* xfer) -{ +static void process_set_config(tuh_xfer_t* xfer) { // Stall is a valid response for SET_IDLE, sometime SET_PROTOCOL as well // therefore we could ignore its result - if ( !(xfer->setup->bRequest == HID_REQ_CONTROL_SET_IDLE || - xfer->setup->bRequest == HID_REQ_CONTROL_SET_PROTOCOL) ) - { - TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS, ); + if (!(xfer->setup->bRequest == HID_REQ_CONTROL_SET_IDLE || + xfer->setup->bRequest == HID_REQ_CONTROL_SET_PROTOCOL)) { + TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS,); } uintptr_t const state = xfer->user_data; uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); - uint8_t const daddr = xfer->daddr; + uint8_t const daddr = xfer->daddr; - uint8_t const idx = tuh_hid_itf_get_index(daddr, itf_num); + uint8_t const idx = tuh_hid_itf_get_index(daddr, itf_num); hidh_interface_t* p_hid = get_hid_itf(daddr, idx); - TU_VERIFY(p_hid, ); + TU_VERIFY(p_hid,); - switch(state) - { - case CONFG_SET_IDLE: - { + switch (state) { + case CONFG_SET_IDLE: { // Idle rate = 0 mean only report when there is changes const uint16_t idle_rate = 0; - const uintptr_t next_state = (p_hid->itf_protocol != HID_ITF_PROTOCOL_NONE) ? CONFIG_SET_PROTOCOL : CONFIG_GET_REPORT_DESC; + const uintptr_t next_state = (p_hid->itf_protocol != HID_ITF_PROTOCOL_NONE) + ? CONFIG_SET_PROTOCOL : CONFIG_GET_REPORT_DESC; _hidh_set_idle(daddr, itf_num, idle_rate, process_set_config, next_state); + break; } - break; case CONFIG_SET_PROTOCOL: _hidh_set_protocol(daddr, p_hid->itf_num, _hidh_default_protocol, process_set_config, CONFIG_GET_REPORT_DESC); - break; + break; case CONFIG_GET_REPORT_DESC: // Get Report Descriptor if possible // using usbh enumeration buffer since report descriptor can be very long - if( p_hid->report_desc_len > CFG_TUH_ENUMERATION_BUFSIZE ) - { + if (p_hid->report_desc_len > CFG_TUH_ENUMERATION_BUFSIZE) { TU_LOG_DRV("HID Skip Report Descriptor since it is too large %u bytes\r\n", p_hid->report_desc_len); // Driver is mounted without report descriptor config_driver_mount_complete(daddr, idx, NULL, 0); - }else - { - tuh_descriptor_get_hid_report(daddr, itf_num, p_hid->report_desc_type, 0, usbh_get_enum_buf(), p_hid->report_desc_len, process_set_config, CONFIG_COMPLETE); + } else { + tuh_descriptor_get_hid_report(daddr, itf_num, p_hid->report_desc_type, 0, + usbh_get_enum_buf(), p_hid->report_desc_len, + process_set_config, CONFIG_COMPLETE); } break; - case CONFIG_COMPLETE: - { + case CONFIG_COMPLETE: { uint8_t const* desc_report = usbh_get_enum_buf(); - uint16_t const desc_len = tu_le16toh(xfer->setup->wLength); + uint16_t const desc_len = tu_le16toh(xfer->setup->wLength); config_driver_mount_complete(daddr, idx, desc_report, desc_len); + break; } - break; - default: break; + default: + break; } } -static void config_driver_mount_complete(uint8_t daddr, uint8_t idx, uint8_t const* desc_report, uint16_t desc_len) -{ +static void config_driver_mount_complete(uint8_t daddr, uint8_t idx, uint8_t const* desc_report, uint16_t desc_len) { hidh_interface_t* p_hid = get_hid_itf(daddr, idx); - TU_VERIFY(p_hid, ); + TU_VERIFY(p_hid,); p_hid->mounted = true; // enumeration is complete @@ -648,21 +570,19 @@ static void config_driver_mount_complete(uint8_t daddr, uint8_t idx, uint8_t con // Report Descriptor Parser //--------------------------------------------------------------------+ -uint8_t tuh_hid_parse_report_descriptor(tuh_hid_report_info_t* report_info_arr, uint8_t arr_count, uint8_t const* desc_report, uint16_t desc_len) -{ +uint8_t tuh_hid_parse_report_descriptor(tuh_hid_report_info_t* report_info_arr, uint8_t arr_count, + uint8_t const* desc_report, uint16_t desc_len) { // Report Item 6.2.2.2 USB HID 1.11 - union TU_ATTR_PACKED - { + union TU_ATTR_PACKED { uint8_t byte; - struct TU_ATTR_PACKED - { - uint8_t size : 2; - uint8_t type : 2; - uint8_t tag : 4; + struct TU_ATTR_PACKED { + uint8_t size : 2; + uint8_t type : 2; + uint8_t tag : 4; }; } header; - tu_memclr(report_info_arr, arr_count*sizeof(tuh_hid_report_info_t)); + tu_memclr(report_info_arr, arr_count * sizeof(tuh_hid_report_info_t)); uint8_t report_num = 0; tuh_hid_report_info_t* info = report_info_arr; @@ -672,114 +592,105 @@ uint8_t tuh_hid_parse_report_descriptor(tuh_hid_report_info_t* report_info_arr, // uint8_t ri_report_size = 0; uint8_t ri_collection_depth = 0; - - while(desc_len && report_num < arr_count) - { + while (desc_len && report_num < arr_count) { header.byte = *desc_report++; desc_len--; - uint8_t const tag = header.tag; + uint8_t const tag = header.tag; uint8_t const type = header.type; uint8_t const size = header.size; 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; iusage_page, desc_report, size); - break; + if (ri_collection_depth == 0) memcpy(&info->usage_page, desc_report, size); + break; - case RI_GLOBAL_LOGICAL_MIN : break; - case RI_GLOBAL_LOGICAL_MAX : break; - case RI_GLOBAL_PHYSICAL_MIN : break; - case RI_GLOBAL_PHYSICAL_MAX : break; + case RI_GLOBAL_LOGICAL_MIN: break; + case RI_GLOBAL_LOGICAL_MAX: break; + case RI_GLOBAL_PHYSICAL_MIN: break; + case RI_GLOBAL_PHYSICAL_MAX: break; case RI_GLOBAL_REPORT_ID: info->report_id = data8; - break; + break; case RI_GLOBAL_REPORT_SIZE: // ri_report_size = data8; - break; + break; case RI_GLOBAL_REPORT_COUNT: // ri_report_count = data8; - break; + break; - case RI_GLOBAL_UNIT_EXPONENT : break; - case RI_GLOBAL_UNIT : break; - case RI_GLOBAL_PUSH : break; - case RI_GLOBAL_POP : break; + case RI_GLOBAL_UNIT_EXPONENT: break; + case RI_GLOBAL_UNIT: break; + case RI_GLOBAL_PUSH: break; + case RI_GLOBAL_POP: break; default: break; } - break; + break; case RI_TYPE_LOCAL: - switch(tag) - { + switch (tag) { case RI_LOCAL_USAGE: // only take in account the "usage" before starting REPORT ID - if ( ri_collection_depth == 0 ) info->usage = data8; - break; + if (ri_collection_depth == 0) info->usage = data8; + break; - case RI_LOCAL_USAGE_MIN : break; - case RI_LOCAL_USAGE_MAX : break; - case RI_LOCAL_DESIGNATOR_INDEX : break; - case RI_LOCAL_DESIGNATOR_MIN : break; - case RI_LOCAL_DESIGNATOR_MAX : break; - case RI_LOCAL_STRING_INDEX : break; - case RI_LOCAL_STRING_MIN : break; - case RI_LOCAL_STRING_MAX : break; - case RI_LOCAL_DELIMITER : break; + case RI_LOCAL_USAGE_MIN: break; + case RI_LOCAL_USAGE_MAX: break; + case RI_LOCAL_DESIGNATOR_INDEX: break; + case RI_LOCAL_DESIGNATOR_MIN: break; + case RI_LOCAL_DESIGNATOR_MAX: break; + case RI_LOCAL_STRING_INDEX: break; + case RI_LOCAL_STRING_MIN: break; + case RI_LOCAL_STRING_MAX: break; + case RI_LOCAL_DELIMITER: break; default: break; } - break; + break; - // error + // error default: break; } desc_report += size; - desc_len -= size; + desc_len -= size; } - for ( uint8_t i = 0; i < report_num; i++ ) - { - info = report_info_arr+i; + for (uint8_t i = 0; i < report_num; i++) { + info = report_info_arr + i; TU_LOG_DRV("%u: id = %u, usage_page = %u, usage = %u\r\n", i, info->report_id, info->usage_page, info->usage); } diff --git a/test/unit-test/project.yml b/test/unit-test/project.yml index 562dbca09..82528f68c 100644 --- a/test/unit-test/project.yml +++ b/test/unit-test/project.yml @@ -44,12 +44,13 @@ # in order to add common defines: # 1) remove the trailing [] from the :common: section # 2) add entries to the :common: section (e.g. :test: has TEST defined) - :common: &common_defines - - _UNITY_TEST_ + :common: &common_defines [] :test: - - *common_defines + - _UNITY_TEST_ + #- *common_defines :test_preprocess: - - *common_defines + - _UNITY_TEST_ + #- *common_defines :cmock: :mock_prefix: mock_ @@ -106,9 +107,9 @@ :flag: "${1}" # or "-L ${1}" for example :common: &common_libraries [] :test: - - *common_libraries + #- *common_libraries :release: - - *common_libraries + #- *common_libraries :plugins: :load_paths: From 4f5d80d3976fb0dc5cd190b1768225aacf34211b Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 1 Mar 2024 17:40:38 +0700 Subject: [PATCH 131/454] add tuh_hid_receive_abort() API --- src/class/hid/hid_host.c | 5 +++++ src/class/hid/hid_host.h | 28 ++++++++++++++++------------ 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 21aee531a..7330fa237 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -320,6 +320,11 @@ bool tuh_hid_receive_report(uint8_t daddr, uint8_t idx) { return true; } +bool tuh_hid_receive_abort(uint8_t dev_addr, uint8_t idx) { + hidh_interface_t* p_hid = get_hid_itf(dev_addr, idx); + TU_VERIFY(p_hid); + return tuh_edpt_abort_xfer(dev_addr, p_hid->ep_in); +} bool tuh_hid_send_ready(uint8_t dev_addr, uint8_t idx) { hidh_interface_t* p_hid = get_hid_itf(dev_addr, idx); diff --git a/src/class/hid/hid_host.h b/src/class/hid/hid_host.h index 238b7c627..17f4e27c0 100644 --- a/src/class/hid/hid_host.h +++ b/src/class/hid/hid_host.h @@ -30,7 +30,7 @@ #include "hid.h" #ifdef __cplusplus - extern "C" { +extern "C" { #endif //--------------------------------------------------------------------+ @@ -47,10 +47,9 @@ #endif -typedef struct -{ - uint8_t report_id; - uint8_t usage; +typedef struct { + uint8_t report_id; + uint8_t usage; uint16_t usage_page; // TODO still use the endpoint size for now @@ -86,7 +85,8 @@ bool tuh_hid_mounted(uint8_t dev_addr, uint8_t idx); // Parse report descriptor into array of report_info struct and return number of reports. // For complicated report, application should write its own parser. -uint8_t tuh_hid_parse_report_descriptor(tuh_hid_report_info_t* reports_info_arr, uint8_t arr_count, uint8_t const* desc_report, uint16_t desc_len) TU_ATTR_UNUSED; +TU_ATTR_UNUSED uint8_t tuh_hid_parse_report_descriptor(tuh_hid_report_info_t* reports_info_arr, uint8_t arr_count, + uint8_t const* desc_report, uint16_t desc_len); //--------------------------------------------------------------------+ // Control Endpoint API @@ -107,7 +107,8 @@ bool tuh_hid_set_protocol(uint8_t dev_addr, uint8_t idx, uint8_t protocol); // Set Report using control endpoint // report_type is either Input, Output or Feature, (value from hid_report_type_t) -bool tuh_hid_set_report(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type, void* report, uint16_t len); +bool tuh_hid_set_report(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type, + void* report, uint16_t len); //--------------------------------------------------------------------+ // Interrupt Endpoint API @@ -121,6 +122,9 @@ bool tuh_hid_receive_ready(uint8_t dev_addr, uint8_t idx); // - false if failed to queue the transfer e.g endpoint is busy bool tuh_hid_receive_report(uint8_t dev_addr, uint8_t idx); +// Abort receiving report on Interrupt Endpoint +bool tuh_hid_receive_abort(uint8_t dev_addr, uint8_t idx); + // Check if HID interface is ready to send report bool tuh_hid_send_ready(uint8_t dev_addr, uint8_t idx); @@ -159,11 +163,11 @@ TU_ATTR_WEAK void tuh_hid_set_protocol_complete_cb(uint8_t dev_addr, uint8_t idx //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ -void hidh_init (void); -bool hidh_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len); -bool hidh_set_config (uint8_t dev_addr, uint8_t itf_num); -bool hidh_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); -void hidh_close (uint8_t dev_addr); +void hidh_init(void); +bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const* desc_itf, uint16_t max_len); +bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num); +bool hidh_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); +void hidh_close(uint8_t dev_addr); #ifdef __cplusplus } From 9b6f13716f34d6a82a60c8c6ec7969d420a8af28 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 4 Mar 2024 16:08:35 +0700 Subject: [PATCH 132/454] correct rp2040 host with max3421 --- examples/host/bare_api/src/tusb_config.h | 2 +- examples/host/cdc_msc_hid/src/tusb_config.h | 2 +- examples/host/cdc_msc_hid_freertos/src/tusb_config.h | 2 +- examples/host/hid_controller/src/tusb_config.h | 2 +- examples/host/msc_file_explorer/src/tusb_config.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/host/bare_api/src/tusb_config.h b/examples/host/bare_api/src/tusb_config.h index 05ffbdf75..432446e94 100644 --- a/examples/host/bare_api/src/tusb_config.h +++ b/examples/host/bare_api/src/tusb_config.h @@ -71,7 +71,7 @@ #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 max3421 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) diff --git a/examples/host/cdc_msc_hid/src/tusb_config.h b/examples/host/cdc_msc_hid/src/tusb_config.h index 76d59c316..a59a0ffb9 100644 --- a/examples/host/cdc_msc_hid/src/tusb_config.h +++ b/examples/host/cdc_msc_hid/src/tusb_config.h @@ -71,7 +71,7 @@ #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 max3421 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) 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 bb7c3388d..35de5ee50 100644 --- a/examples/host/cdc_msc_hid_freertos/src/tusb_config.h +++ b/examples/host/cdc_msc_hid_freertos/src/tusb_config.h @@ -76,7 +76,7 @@ #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 max3421 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) diff --git a/examples/host/hid_controller/src/tusb_config.h b/examples/host/hid_controller/src/tusb_config.h index 8ddaddda7..3ac591d8f 100644 --- a/examples/host/hid_controller/src/tusb_config.h +++ b/examples/host/hid_controller/src/tusb_config.h @@ -71,7 +71,7 @@ #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 max3421 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) diff --git a/examples/host/msc_file_explorer/src/tusb_config.h b/examples/host/msc_file_explorer/src/tusb_config.h index 1703761a4..c798b4383 100644 --- a/examples/host/msc_file_explorer/src/tusb_config.h +++ b/examples/host/msc_file_explorer/src/tusb_config.h @@ -71,7 +71,7 @@ #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 max3421 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) From ff76eca311f4026c1a9b36e9ad37bbb53b39cf5d Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 4 Mar 2024 16:15:26 +0700 Subject: [PATCH 133/454] code reformat --- src/host/usbh.c | 563 +++++++++++++++++++++--------------------------- src/tusb.c | 12 +- 2 files changed, 245 insertions(+), 330 deletions(-) diff --git a/src/host/usbh.c b/src/host/usbh.c index f56290a0c..407d97234 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -420,20 +420,18 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { (void) in_isr; // not implemented yet // Skip if stack is not initialized - if ( !tuh_inited() ) return; + if (!tuh_inited()) return; // Loop until there is no more events in the queue - while (1) - { + while (1) { hcd_event_t event; - if ( !osal_queue_receive(_usbh_q, &event, timeout_ms) ) return; + if (!osal_queue_receive(_usbh_q, &event, timeout_ms)) return; - switch (event.event_id) - { + switch (event.event_id) { case HCD_EVENT_DEVICE_ATTACH: // due to the shared _usbh_ctrl_buf, we must complete enumerating one device before enumerating another one. // TODO better to have an separated queue for newly attached devices - if ( _dev0.enumerating ) { + if (_dev0.enumerating) { TU_LOG_USBH("[%u:] USBH Defer Attach until current enumeration complete\r\n", event.rhport); bool is_empty = osal_queue_empty(_usbh_q); @@ -443,12 +441,12 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { // Exit if this is the only event in the queue, otherwise we may loop forever return; } - }else { + } else { TU_LOG_USBH("[%u:] USBH DEVICE ATTACH\r\n", event.rhport); _dev0.enumerating = 1; enum_new_device(&event); } - break; + break; case HCD_EVENT_DEVICE_REMOVE: TU_LOG_USBH("[%u:%u:%u] USBH DEVICE REMOVED\r\n", event.rhport, event.connection.hub_addr, event.connection.hub_port); @@ -456,37 +454,34 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { #if CFG_TUH_HUB // TODO remove - if ( event.connection.hub_addr != 0 && event.connection.hub_port != 0) { + if (event.connection.hub_addr != 0 && event.connection.hub_port != 0) { // done with hub, waiting for next data on status pipe - (void) hub_edpt_status_xfer( event.connection.hub_addr ); + (void) hub_edpt_status_xfer(event.connection.hub_addr); } #endif - break; + break; - case HCD_EVENT_XFER_COMPLETE: - { + case HCD_EVENT_XFER_COMPLETE: { uint8_t const ep_addr = event.xfer_complete.ep_addr; - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const ep_dir = tu_edpt_dir(ep_addr); + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const ep_dir = (uint8_t) tu_edpt_dir(ep_addr); - TU_LOG_USBH("on EP %02X with %u bytes: %s\r\n", ep_addr, (unsigned int) event.xfer_complete.len, - tu_str_xfer_result[event.xfer_complete.result]); + TU_LOG_USBH("on EP %02X with %u bytes: %s\r\n", ep_addr, (unsigned int) event.xfer_complete.len, tu_str_xfer_result[event.xfer_complete.result]); if (event.dev_addr == 0) { // device 0 only has control endpoint - TU_ASSERT(epnum == 0, ); + TU_ASSERT(epnum == 0,); usbh_control_xfer_cb(event.dev_addr, ep_addr, (xfer_result_t) event.xfer_complete.result, event.xfer_complete.len); } else { usbh_device_t* dev = get_device(event.dev_addr); - TU_VERIFY(dev && dev->connected, ); + TU_VERIFY(dev && dev->connected,); - dev->ep_status[epnum][ep_dir].busy = 0; + dev->ep_status[epnum][ep_dir].busy = 0; dev->ep_status[epnum][ep_dir].claimed = 0; - if ( 0 == epnum ) { - usbh_control_xfer_cb(event.dev_addr, ep_addr, (xfer_result_t) event.xfer_complete.result, - event.xfer_complete.len); - }else { + if (0 == epnum) { + usbh_control_xfer_cb(event.dev_addr, ep_addr, (xfer_result_t) event.xfer_complete.result, event.xfer_complete.len); + } else { // Prefer application callback over built-in one if available. This occurs when tuh_edpt_xfer() is used // with enabled driver e.g HID endpoint #if CFG_TUH_API_EDPT_XFER @@ -503,35 +498,32 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { .complete_cb = complete_cb, .user_data = dev->ep_callback[epnum][ep_dir].user_data }; - complete_cb(&xfer); }else #endif { uint8_t drv_id = dev->ep2drv[epnum][ep_dir]; - usbh_class_driver_t const * driver = get_driver(drv_id); - if ( driver ) - { + usbh_class_driver_t const* driver = get_driver(drv_id); + if (driver) { TU_LOG_USBH("%s xfer callback\r\n", driver->name); driver->xfer_cb(event.dev_addr, ep_addr, (xfer_result_t) event.xfer_complete.result, event.xfer_complete.len); - } - else - { + } else { // no driver/callback responsible for this transfer TU_ASSERT(false,); } } } } + break; } - break; case USBH_EVENT_FUNC_CALL: - if ( event.func_call.func ) event.func_call.func(event.func_call.param); - break; + if (event.func_call.func) event.func_call.func(event.func_call.param); + break; - default: break; + default: + break; } #if CFG_TUSB_OS != OPT_OS_NONE && CFG_TUSB_OS != OPT_OS_PICO @@ -708,7 +700,6 @@ bool tuh_edpt_xfer(tuh_xfer_t* xfer) { uint8_t const ep_addr = xfer->ep_addr; TU_VERIFY(daddr && ep_addr); - TU_VERIFY(usbh_edpt_claim(daddr, ep_addr)); if (!usbh_edpt_xfer_with_callback(daddr, ep_addr, xfer->buffer, (uint16_t) xfer->buflen, @@ -783,14 +774,13 @@ void usbh_defer_func(osal_task_func_t func, void *param, bool in_isr) { //--------------------------------------------------------------------+ // Claim an endpoint for transfer -bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr) -{ +bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr) { // Note: addr0 only use tuh_control_xfer usbh_device_t* dev = get_device(dev_addr); TU_ASSERT(dev && dev->connected); uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); TU_VERIFY(tu_edpt_claim(&dev->ep_status[epnum][dir], _usbh_mutex)); TU_LOG_USBH("[%u] Claimed EP 0x%02x\r\n", dev_addr, ep_addr); @@ -799,14 +789,13 @@ bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr) } // Release an claimed endpoint due to failed transfer attempt -bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr) -{ +bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr) { // Note: addr0 only use tuh_control_xfer usbh_device_t* dev = get_device(dev_addr); TU_VERIFY(dev && dev->connected); uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); TU_VERIFY(tu_edpt_release(&dev->ep_status[epnum][dir], _usbh_mutex)); TU_LOG_USBH("[%u] Released EP 0x%02x\r\n", dev_addr, ep_addr); @@ -816,9 +805,8 @@ bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr) // Submit an transfer // TODO call usbh_edpt_release if failed -bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ +bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { (void) complete_cb; (void) user_data; @@ -826,7 +814,7 @@ bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * b TU_VERIFY(dev); uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); tu_edpt_state_t* ep_state = &dev->ep_status[epnum][dir]; TU_LOG_USBH(" Queue EP %02X with %u bytes ... \r\n", ep_addr, total_bytes); @@ -843,14 +831,12 @@ bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * b dev->ep_callback[epnum][dir].user_data = user_data; #endif - if ( hcd_edpt_xfer(dev->rhport, dev_addr, ep_addr, buffer, total_bytes) ) - { + if (hcd_edpt_xfer(dev->rhport, dev_addr, ep_addr, buffer, total_bytes)) { TU_LOG_USBH("OK\r\n"); return true; - }else - { + } else { // HCD error, mark endpoint as ready to allow next transfer - ep_state->busy = 0; + ep_state->busy = 0; ep_state->claimed = 0; TU_LOG1("Failed\r\n"); // TU_BREAKPOINT(); @@ -858,12 +844,9 @@ bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * b } } -static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size) -{ +static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size) { TU_LOG_USBH("[%u:%u] Open EP0 with Size = %u\r\n", usbh_get_rhport(dev_addr), dev_addr, max_packet_size); - - tusb_desc_endpoint_t ep0_desc = - { + tusb_desc_endpoint_t ep0_desc = { .bLength = sizeof(tusb_desc_endpoint_t), .bDescriptorType = TUSB_DESC_ENDPOINT, .bEndpointAddress = 0, @@ -875,10 +858,8 @@ static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size) return hcd_edpt_open(usbh_get_rhport(dev_addr), dev_addr, &ep0_desc); } -bool tuh_edpt_open(uint8_t dev_addr, tusb_desc_endpoint_t const * desc_ep) -{ - TU_ASSERT( tu_edpt_validate(desc_ep, tuh_speed_get(dev_addr)) ); - +bool tuh_edpt_open(uint8_t dev_addr, tusb_desc_endpoint_t const* desc_ep) { + TU_ASSERT(tu_edpt_validate(desc_ep, tuh_speed_get(dev_addr))); return hcd_edpt_open(usbh_get_rhport(dev_addr), dev_addr, desc_ep); } @@ -887,7 +868,7 @@ bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr) { TU_VERIFY(dev); uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); return dev->ep_status[epnum][dir].busy; } @@ -896,22 +877,18 @@ bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr) { // HCD Event Handler //--------------------------------------------------------------------+ -void hcd_devtree_get_info(uint8_t dev_addr, hcd_devtree_info_t* devtree_info) -{ +void hcd_devtree_get_info(uint8_t dev_addr, hcd_devtree_info_t* devtree_info) { usbh_device_t const* dev = get_device(dev_addr); - - if (dev) - { - devtree_info->rhport = dev->rhport; + if (dev) { + devtree_info->rhport = dev->rhport; devtree_info->hub_addr = dev->hub_addr; devtree_info->hub_port = dev->hub_port; - devtree_info->speed = dev->speed; - }else - { - devtree_info->rhport = _dev0.rhport; + devtree_info->speed = dev->speed; + } else { + devtree_info->rhport = _dev0.rhport; devtree_info->hub_addr = _dev0.hub_addr; devtree_info->hub_port = _dev0.hub_port; - devtree_info->speed = _dev0.speed; + devtree_info->speed = _dev0.speed; } } @@ -941,12 +918,9 @@ TU_ATTR_FAST_FUNC void hcd_event_handler(hcd_event_t const* event, bool in_isr) // generic helper to get a descriptor // if blocking, user_data is pointed to xfer_result static bool _get_descriptor(uint8_t daddr, uint8_t type, uint8_t index, uint16_t language_id, void* buffer, uint16_t len, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ - tusb_control_request_t const request = - { - .bmRequestType_bit = - { + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + tusb_control_request_t const request = { + .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_DEVICE, .type = TUSB_REQ_TYPE_STANDARD, .direction = TUSB_DIR_IN @@ -956,9 +930,7 @@ static bool _get_descriptor(uint8_t daddr, uint8_t type, uint8_t index, uint16_t .wIndex = tu_htole16(language_id), .wLength = tu_htole16(len) }; - - tuh_xfer_t xfer = - { + tuh_xfer_t xfer = { .daddr = daddr, .ep_addr = 0, .setup = &request, @@ -971,29 +943,25 @@ static bool _get_descriptor(uint8_t daddr, uint8_t type, uint8_t index, uint16_t } bool tuh_descriptor_get(uint8_t daddr, uint8_t type, uint8_t index, void* buffer, uint16_t len, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return _get_descriptor(daddr, type, index, 0x0000, buffer, len, complete_cb, user_data); } bool tuh_descriptor_get_device(uint8_t daddr, void* buffer, uint16_t len, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { len = tu_min16(len, sizeof(tusb_desc_device_t)); return tuh_descriptor_get(daddr, TUSB_DESC_DEVICE, 0, buffer, len, complete_cb, user_data); } bool tuh_descriptor_get_configuration(uint8_t daddr, uint8_t index, void* buffer, uint16_t len, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return tuh_descriptor_get(daddr, TUSB_DESC_CONFIGURATION, index, buffer, len, complete_cb, user_data); } //------------- String Descriptor -------------// bool tuh_descriptor_get_string(uint8_t daddr, uint8_t index, uint16_t language_id, void* buffer, uint16_t len, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return _get_descriptor(daddr, TUSB_DESC_STRING, index, language_id, buffer, len, complete_cb, user_data); } @@ -1008,8 +976,7 @@ bool tuh_descriptor_get_manufacturer_string(uint8_t daddr, uint16_t language_id, // Get product string descriptor bool tuh_descriptor_get_product_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { usbh_device_t const* dev = get_device(daddr); TU_VERIFY(dev && dev->i_product); return tuh_descriptor_get_string(daddr, dev->i_product, language_id, buffer, len, complete_cb, user_data); @@ -1017,8 +984,7 @@ bool tuh_descriptor_get_product_string(uint8_t daddr, uint16_t language_id, void // Get serial string descriptor bool tuh_descriptor_get_serial_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { usbh_device_t const* dev = get_device(daddr); TU_VERIFY(dev && dev->i_serial); return tuh_descriptor_get_string(daddr, dev->i_serial, language_id, buffer, len, complete_cb, user_data); @@ -1027,95 +993,78 @@ bool tuh_descriptor_get_serial_string(uint8_t daddr, uint16_t language_id, void* // Get HID report descriptor // if blocking, user_data is pointed to xfer_result bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, uint8_t index, void* buffer, uint16_t len, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { TU_LOG_USBH("HID Get Report Descriptor\r\n"); - tusb_control_request_t const request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_STANDARD, - .direction = TUSB_DIR_IN - }, - .bRequest = TUSB_REQ_GET_DESCRIPTOR, - .wValue = tu_htole16(TU_U16(desc_type, index)), - .wIndex = tu_htole16((uint16_t) itf_num), - .wLength = len + tusb_control_request_t const request = { + .bmRequestType_bit = { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_IN + }, + .bRequest = TUSB_REQ_GET_DESCRIPTOR, + .wValue = tu_htole16(TU_U16(desc_type, index)), + .wIndex = tu_htole16((uint16_t) itf_num), + .wLength = len }; - - tuh_xfer_t xfer = - { - .daddr = daddr, - .ep_addr = 0, - .setup = &request, - .buffer = buffer, - .complete_cb = complete_cb, - .user_data = user_data + tuh_xfer_t xfer = { + .daddr = daddr, + .ep_addr = 0, + .setup = &request, + .buffer = buffer, + .complete_cb = complete_cb, + .user_data = user_data }; return tuh_control_xfer(&xfer); } bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { TU_LOG_USBH("Set Configuration = %d\r\n", config_num); - - tusb_control_request_t const request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_DEVICE, - .type = TUSB_REQ_TYPE_STANDARD, - .direction = TUSB_DIR_OUT - }, - .bRequest = TUSB_REQ_SET_CONFIGURATION, - .wValue = tu_htole16(config_num), - .wIndex = 0, - .wLength = 0 + tusb_control_request_t const request = { + .bmRequestType_bit = { + .recipient = TUSB_REQ_RCPT_DEVICE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_OUT + }, + .bRequest = TUSB_REQ_SET_CONFIGURATION, + .wValue = tu_htole16(config_num), + .wIndex = 0, + .wLength = 0 }; - - tuh_xfer_t xfer = - { - .daddr = daddr, - .ep_addr = 0, - .setup = &request, - .buffer = NULL, - .complete_cb = complete_cb, - .user_data = user_data + tuh_xfer_t xfer = { + .daddr = daddr, + .ep_addr = 0, + .setup = &request, + .buffer = NULL, + .complete_cb = complete_cb, + .user_data = user_data }; return tuh_control_xfer(&xfer); } bool tuh_interface_set(uint8_t daddr, uint8_t itf_num, uint8_t itf_alt, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { 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, - .type = TUSB_REQ_TYPE_STANDARD, - .direction = TUSB_DIR_OUT - }, - .bRequest = TUSB_REQ_SET_INTERFACE, - .wValue = tu_htole16(itf_alt), - .wIndex = tu_htole16(itf_num), - .wLength = 0 + tusb_control_request_t const request = { + .bmRequestType_bit = { + .recipient = TUSB_REQ_RCPT_DEVICE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_OUT + }, + .bRequest = TUSB_REQ_SET_INTERFACE, + .wValue = tu_htole16(itf_alt), + .wIndex = tu_htole16(itf_num), + .wLength = 0 }; - - tuh_xfer_t xfer = - { - .daddr = daddr, - .ep_addr = 0, - .setup = &request, - .buffer = NULL, - .complete_cb = complete_cb, - .user_data = user_data + tuh_xfer_t xfer = { + .daddr = daddr, + .ep_addr = 0, + .setup = &request, + .buffer = NULL, + .complete_cb = complete_cb, + .user_data = user_data }; return tuh_control_xfer(&xfer); @@ -1174,9 +1123,7 @@ uint8_t tuh_descriptor_get_serial_string_sync(uint8_t daddr, uint16_t language_i // Detaching //--------------------------------------------------------------------+ -TU_ATTR_ALWAYS_INLINE -static inline bool is_hub_addr(uint8_t daddr) -{ +TU_ATTR_ALWAYS_INLINE static inline bool is_hub_addr(uint8_t daddr) { return (CFG_TUH_HUB > 0) && (daddr > CFG_TUH_DEVICE_MAX); } @@ -1201,8 +1148,7 @@ static inline bool is_hub_addr(uint8_t daddr) //} // a device unplugged from rhport:hub_addr:hub_port -static void process_removing_device(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port) -{ +static void process_removing_device(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port) { //------------- find the all devices (star-network) under port that is unplugged -------------// // TODO mark as disconnected in ISR, also handle dev0 @@ -1217,8 +1163,7 @@ static void process_removing_device(uint8_t rhport, uint8_t hub_addr, uint8_t hu uint8_t nop_count = 0; #endif - for (uint8_t dev_id = 0; dev_id < TOTAL_DEVICES; dev_id++) - { + for (uint8_t dev_id = 0; dev_id < TOTAL_DEVICES; dev_id++) { usbh_device_t *dev = &_usbh_devices[dev_id]; uint8_t const daddr = dev_id + 1; @@ -1325,165 +1270,160 @@ static void process_enumeration(tuh_xfer_t* xfer) { uint8_t const daddr = xfer->daddr; uintptr_t const state = xfer->user_data; - switch(state) - { -#if CFG_TUH_HUB + switch (state) { + #if CFG_TUH_HUB //case ENUM_HUB_GET_STATUS_1: break; - case ENUM_HUB_CLEAR_RESET_1: - { + case ENUM_HUB_CLEAR_RESET_1: { hub_port_status_response_t port_status; memcpy(&port_status, _usbh_ctrl_buf, sizeof(hub_port_status_response_t)); - if ( !port_status.status.connection ) - { + if (!port_status.status.connection) { // device unplugged while delaying, nothing else to do enum_full_complete(); return; } _dev0.speed = (port_status.status.high_speed) ? TUSB_SPEED_HIGH : - (port_status.status.low_speed ) ? TUSB_SPEED_LOW : TUSB_SPEED_FULL; + (port_status.status.low_speed) ? TUSB_SPEED_LOW : TUSB_SPEED_FULL; // Acknowledge Port Reset Change - if (port_status.change.reset) - { - hub_port_clear_reset_change(_dev0.hub_addr, _dev0.hub_port, process_enumeration, ENUM_ADDR0_DEVICE_DESC); + if (port_status.change.reset) { + hub_port_clear_reset_change(_dev0.hub_addr, _dev0.hub_port, + process_enumeration, ENUM_ADDR0_DEVICE_DESC); } + break; } - break; case ENUM_HUB_GET_STATUS_2: osal_task_delay(ENUM_RESET_DELAY); - TU_ASSERT( hub_port_get_status(_dev0.hub_addr, _dev0.hub_port, _usbh_ctrl_buf, process_enumeration, ENUM_HUB_CLEAR_RESET_2), ); - break; + TU_ASSERT(hub_port_get_status(_dev0.hub_addr, _dev0.hub_port, _usbh_ctrl_buf, + process_enumeration, ENUM_HUB_CLEAR_RESET_2),); + break; - case ENUM_HUB_CLEAR_RESET_2: - { + case ENUM_HUB_CLEAR_RESET_2: { hub_port_status_response_t port_status; memcpy(&port_status, _usbh_ctrl_buf, sizeof(hub_port_status_response_t)); // Acknowledge Port Reset Change if Reset Successful - if (port_status.change.reset) - { - TU_ASSERT( hub_port_clear_reset_change(_dev0.hub_addr, _dev0.hub_port, process_enumeration, ENUM_SET_ADDR), ); + if (port_status.change.reset) { + TU_ASSERT(hub_port_clear_reset_change(_dev0.hub_addr, _dev0.hub_port, + process_enumeration, ENUM_SET_ADDR),); } + break; } - break; -#endif + #endif - case ENUM_ADDR0_DEVICE_DESC: - { + case ENUM_ADDR0_DEVICE_DESC: { // TODO probably doesn't need to open/close each enumeration uint8_t const addr0 = 0; - TU_ASSERT( usbh_edpt_control_open(addr0, 8), ); + TU_ASSERT(usbh_edpt_control_open(addr0, 8),); // Get first 8 bytes of device descriptor for Control Endpoint size TU_LOG_USBH("Get 8 byte of Device Descriptor\r\n"); - TU_ASSERT(tuh_descriptor_get_device(addr0, _usbh_ctrl_buf, 8, process_enumeration, ENUM_SET_ADDR), ); + TU_ASSERT(tuh_descriptor_get_device(addr0, _usbh_ctrl_buf, 8, + process_enumeration, ENUM_SET_ADDR),); + break; } - break; #if 0 - case ENUM_RESET_2: - // TODO not used by now, but may be needed for some devices !? - // Reset device again before Set Address - TU_LOG_USBH("Port reset2 \r\n"); - if (_dev0.hub_addr == 0) - { - // connected directly to roothub - hcd_port_reset( _dev0.rhport ); - osal_task_delay(RESET_DELAY); // TODO may not work for no-OS on MCU that require reset_end() since - // sof of controller may not running while resetting - hcd_port_reset_end(_dev0.rhport); - // TODO: fall through to SET ADDRESS, refactor later - } - #if CFG_TUH_HUB - else - { - // after RESET_DELAY the hub_port_reset() already complete - TU_ASSERT( hub_port_reset(_dev0.hub_addr, _dev0.hub_port, process_enumeration, ENUM_HUB_GET_STATUS_2), ); - break; - } - #endif - TU_ATTR_FALLTHROUGH; + case ENUM_RESET_2: + // TODO not used by now, but may be needed for some devices !? + // Reset device again before Set Address + TU_LOG_USBH("Port reset2 \r\n"); + if (_dev0.hub_addr == 0) { + // connected directly to roothub + hcd_port_reset( _dev0.rhport ); + osal_task_delay(RESET_DELAY); // TODO may not work for no-OS on MCU that require reset_end() since + // sof of controller may not running while resetting + hcd_port_reset_end(_dev0.rhport); + // TODO: fall through to SET ADDRESS, refactor later + } +#if CFG_TUH_HUB + else { + // after RESET_DELAY the hub_port_reset() already complete + TU_ASSERT( hub_port_reset(_dev0.hub_addr, _dev0.hub_port, + process_enumeration, ENUM_HUB_GET_STATUS_2), ); + break; + } +#endif + TU_ATTR_FALLTHROUGH; #endif case ENUM_SET_ADDR: enum_request_set_addr(); - break; + break; - case ENUM_GET_DEVICE_DESC: - { + case ENUM_GET_DEVICE_DESC: { uint8_t const new_addr = (uint8_t) tu_le16toh(xfer->setup->wValue); usbh_device_t* new_dev = get_device(new_addr); - TU_ASSERT(new_dev, ); + TU_ASSERT(new_dev,); new_dev->addressed = 1; // Close device 0 hcd_device_close(_dev0.rhport, 0); // open control pipe for new address - TU_ASSERT( usbh_edpt_control_open(new_addr, new_dev->ep0_size), ); + TU_ASSERT(usbh_edpt_control_open(new_addr, new_dev->ep0_size),); // Get full device descriptor TU_LOG_USBH("Get Device Descriptor\r\n"); - TU_ASSERT(tuh_descriptor_get_device(new_addr, _usbh_ctrl_buf, sizeof(tusb_desc_device_t), process_enumeration, ENUM_GET_9BYTE_CONFIG_DESC), ); + TU_ASSERT(tuh_descriptor_get_device(new_addr, _usbh_ctrl_buf, sizeof(tusb_desc_device_t), + process_enumeration, ENUM_GET_9BYTE_CONFIG_DESC),); + break; } - break; - case ENUM_GET_9BYTE_CONFIG_DESC: - { - tusb_desc_device_t const * desc_device = (tusb_desc_device_t const*) _usbh_ctrl_buf; + case ENUM_GET_9BYTE_CONFIG_DESC: { + tusb_desc_device_t const* desc_device = (tusb_desc_device_t const*) _usbh_ctrl_buf; usbh_device_t* dev = get_device(daddr); - TU_ASSERT(dev, ); + TU_ASSERT(dev,); - dev->vid = desc_device->idVendor; - dev->pid = desc_device->idProduct; + dev->vid = desc_device->idVendor; + dev->pid = desc_device->idProduct; dev->i_manufacturer = desc_device->iManufacturer; - dev->i_product = desc_device->iProduct; - dev->i_serial = desc_device->iSerialNumber; + dev->i_product = desc_device->iProduct; + dev->i_serial = desc_device->iSerialNumber; - // if (tuh_attach_cb) tuh_attach_cb((tusb_desc_device_t*) _usbh_ctrl_buf); + // if (tuh_attach_cb) tuh_attach_cb((tusb_desc_device_t*) _usbh_ctrl_buf); // Get 9-byte for total length uint8_t const config_idx = CONFIG_NUM - 1; TU_LOG_USBH("Get Configuration[0] Descriptor (9 bytes)\r\n"); - TU_ASSERT( tuh_descriptor_get_configuration(daddr, config_idx, _usbh_ctrl_buf, 9, process_enumeration, ENUM_GET_FULL_CONFIG_DESC), ); + TU_ASSERT(tuh_descriptor_get_configuration(daddr, config_idx, _usbh_ctrl_buf, 9, + process_enumeration, ENUM_GET_FULL_CONFIG_DESC),); + break; } - break; - case ENUM_GET_FULL_CONFIG_DESC: - { - uint8_t const * desc_config = _usbh_ctrl_buf; + case ENUM_GET_FULL_CONFIG_DESC: { + uint8_t const* desc_config = _usbh_ctrl_buf; // Use offsetof to avoid pointer to the odd/misaligned address - uint16_t const total_len = tu_le16toh( tu_unaligned_read16(desc_config + offsetof(tusb_desc_configuration_t, wTotalLength)) ); + uint16_t const total_len = tu_le16toh( + tu_unaligned_read16(desc_config + offsetof(tusb_desc_configuration_t, wTotalLength))); // TODO not enough buffer to hold configuration descriptor - TU_ASSERT(total_len <= CFG_TUH_ENUMERATION_BUFSIZE, ); + TU_ASSERT(total_len <= CFG_TUH_ENUMERATION_BUFSIZE,); // Get full configuration descriptor uint8_t const config_idx = CONFIG_NUM - 1; TU_LOG_USBH("Get Configuration[0] Descriptor\r\n"); - TU_ASSERT( tuh_descriptor_get_configuration(daddr, config_idx, _usbh_ctrl_buf, total_len, process_enumeration, ENUM_SET_CONFIG), ); + TU_ASSERT(tuh_descriptor_get_configuration(daddr, config_idx, _usbh_ctrl_buf, total_len, + process_enumeration, ENUM_SET_CONFIG),); + break; } - break; case ENUM_SET_CONFIG: // Parse configuration & set up drivers // Driver open aren't allowed to make any usb transfer yet - TU_ASSERT( _parse_configuration_descriptor(daddr, (tusb_desc_configuration_t*) _usbh_ctrl_buf), ); + TU_ASSERT(_parse_configuration_descriptor(daddr, (tusb_desc_configuration_t*) _usbh_ctrl_buf),); + TU_ASSERT(tuh_configuration_set(daddr, CONFIG_NUM, process_enumeration, ENUM_CONFIG_DRIVER),); + break; - TU_ASSERT( tuh_configuration_set(daddr, CONFIG_NUM, process_enumeration, ENUM_CONFIG_DRIVER), ); - break; - - case ENUM_CONFIG_DRIVER: - { + case ENUM_CONFIG_DRIVER: { TU_LOG_USBH("Device configured\r\n"); usbh_device_t* dev = get_device(daddr); - TU_ASSERT(dev, ); + TU_ASSERT(dev,); dev->configured = 1; @@ -1492,60 +1432,58 @@ static void process_enumeration(tuh_xfer_t* xfer) { // The process continue with next interface when class driver complete its sequence with usbh_driver_set_config_complete() // TODO use separated API instead of using TUSB_INDEX_INVALID_8 usbh_driver_set_config_complete(daddr, TUSB_INDEX_INVALID_8); + break; } - break; default: // stop enumeration if unknown state enum_full_complete(); - break; + break; } } -static bool enum_new_device(hcd_event_t* event) -{ - _dev0.rhport = event->rhport; +static bool enum_new_device(hcd_event_t* event) { + _dev0.rhport = event->rhport; _dev0.hub_addr = event->connection.hub_addr; _dev0.hub_port = event->connection.hub_port; - if (_dev0.hub_addr == 0) - { + if (_dev0.hub_addr == 0) { // connected/disconnected directly with roothub hcd_port_reset(_dev0.rhport); osal_task_delay(ENUM_RESET_DELAY); // TODO may not work for no-OS on MCU that require reset_end() since - // sof of controller may not running while resetting - hcd_port_reset_end( _dev0.rhport); + // sof of controller may not running while resetting + hcd_port_reset_end(_dev0.rhport); // wait until device connection is stable TODO non blocking osal_task_delay(ENUM_CONTACT_DEBOUNCING_DELAY); // device unplugged while delaying - if ( !hcd_port_connect_status(_dev0.rhport) ) { + if (!hcd_port_connect_status(_dev0.rhport)) { enum_full_complete(); return true; } - _dev0.speed = hcd_port_speed_get(_dev0.rhport ); + _dev0.speed = hcd_port_speed_get(_dev0.rhport); TU_LOG_USBH("%s Speed\r\n", tu_str_speed[_dev0.speed]); // fake transfer to kick-off the enumeration process tuh_xfer_t xfer; - xfer.daddr = 0; - xfer.result = XFER_RESULT_SUCCESS; + xfer.daddr = 0; + xfer.result = XFER_RESULT_SUCCESS; xfer.user_data = ENUM_ADDR0_DEVICE_DESC; process_enumeration(&xfer); } #if CFG_TUH_HUB - else - { + else { // connected/disconnected via external hub // wait until device connection is stable TODO non blocking osal_task_delay(ENUM_CONTACT_DEBOUNCING_DELAY); // ENUM_HUB_GET_STATUS //TU_ASSERT( hub_port_get_status(_dev0.hub_addr, _dev0.hub_port, _usbh_ctrl_buf, enum_hub_get_status0_complete, 0) ); - TU_ASSERT( hub_port_get_status(_dev0.hub_addr, _dev0.hub_port, _usbh_ctrl_buf, process_enumeration, ENUM_HUB_CLEAR_RESET_1) ); + TU_ASSERT(hub_port_get_status(_dev0.hub_addr, _dev0.hub_port, _usbh_ctrl_buf, + process_enumeration, ENUM_HUB_CLEAR_RESET_1)); } #endif // hub @@ -1571,58 +1509,48 @@ static uint8_t get_new_address(bool is_hub) { return 0; // invalid address } -static bool enum_request_set_addr(void) -{ - tusb_desc_device_t const * desc_device = (tusb_desc_device_t const*) _usbh_ctrl_buf; +static bool enum_request_set_addr(void) { + tusb_desc_device_t const* desc_device = (tusb_desc_device_t const*) _usbh_ctrl_buf; // Get new address uint8_t const new_addr = get_new_address(desc_device->bDeviceClass == TUSB_CLASS_HUB); TU_ASSERT(new_addr != 0); - TU_LOG_USBH("Set Address = %d\r\n", new_addr); usbh_device_t* new_dev = get_device(new_addr); - - new_dev->rhport = _dev0.rhport; - new_dev->hub_addr = _dev0.hub_addr; - new_dev->hub_port = _dev0.hub_port; - new_dev->speed = _dev0.speed; + new_dev->rhport = _dev0.rhport; + new_dev->hub_addr = _dev0.hub_addr; + new_dev->hub_port = _dev0.hub_port; + new_dev->speed = _dev0.speed; new_dev->connected = 1; - new_dev->ep0_size = desc_device->bMaxPacketSize0; + new_dev->ep0_size = desc_device->bMaxPacketSize0; - tusb_control_request_t const request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_DEVICE, - .type = TUSB_REQ_TYPE_STANDARD, - .direction = TUSB_DIR_OUT - }, - .bRequest = TUSB_REQ_SET_ADDRESS, - .wValue = tu_htole16(new_addr), - .wIndex = 0, - .wLength = 0 + tusb_control_request_t const request = { + .bmRequestType_bit = { + .recipient = TUSB_REQ_RCPT_DEVICE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_OUT + }, + .bRequest = TUSB_REQ_SET_ADDRESS, + .wValue = tu_htole16(new_addr), + .wIndex = 0, + .wLength = 0 + }; + tuh_xfer_t xfer = { + .daddr = 0, // dev0 + .ep_addr = 0, + .setup = &request, + .buffer = NULL, + .complete_cb = process_enumeration, + .user_data = ENUM_GET_DEVICE_DESC }; - tuh_xfer_t xfer = - { - .daddr = 0, // dev0 - .ep_addr = 0, - .setup = &request, - .buffer = NULL, - .complete_cb = process_enumeration, - .user_data = ENUM_GET_DEVICE_DESC - }; - - TU_ASSERT( tuh_control_xfer(&xfer) ); - + TU_ASSERT(tuh_control_xfer(&xfer)); return true; } -static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configuration_t const* desc_cfg) -{ +static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configuration_t const* desc_cfg) { usbh_device_t* dev = get_device(dev_addr); - uint16_t const total_len = tu_le16toh(desc_cfg->wTotalLength); uint8_t const* desc_end = ((uint8_t const*) desc_cfg) + total_len; uint8_t const* p_desc = tu_desc_next(desc_cfg); @@ -1630,13 +1558,11 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur TU_LOG_USBH("Parsing Configuration descriptor (wTotalLength = %u)\r\n", total_len); // parse each interfaces - while( p_desc < desc_end ) - { + while( p_desc < desc_end ) { uint8_t assoc_itf_count = 1; // Class will always starts with Interface Association (if any) and then Interface descriptor - if ( TUSB_DESC_INTERFACE_ASSOCIATION == tu_desc_type(p_desc) ) - { + if ( TUSB_DESC_INTERFACE_ASSOCIATION == tu_desc_type(p_desc) ) { tusb_desc_interface_assoc_t const * desc_iad = (tusb_desc_interface_assoc_t const *) p_desc; assoc_itf_count = desc_iad->bInterfaceCount; @@ -1656,8 +1582,7 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur if (1 == assoc_itf_count && TUSB_CLASS_AUDIO == desc_itf->bInterfaceClass && AUDIO_SUBCLASS_CONTROL == desc_itf->bInterfaceSubClass && - AUDIO_FUNC_PROTOCOL_CODE_UNDEF == desc_itf->bInterfaceProtocol) - { + AUDIO_FUNC_PROTOCOL_CODE_UNDEF == desc_itf->bInterfaceProtocol) { assoc_itf_count = 2; } #endif @@ -1667,8 +1592,7 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur // manually force associated count = 2 if (1 == assoc_itf_count && TUSB_CLASS_CDC == desc_itf->bInterfaceClass && - CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == desc_itf->bInterfaceSubClass) - { + CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == desc_itf->bInterfaceSubClass) { assoc_itf_count = 2; } #endif @@ -1677,18 +1601,14 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur TU_ASSERT(drv_len >= sizeof(tusb_desc_interface_t)); // Find driver for this interface - for (uint8_t drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) - { + for (uint8_t drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) { usbh_class_driver_t const * driver = get_driver(drv_id); - - if (driver && driver->open(dev->rhport, dev_addr, desc_itf, drv_len) ) - { + if (driver && driver->open(dev->rhport, dev_addr, desc_itf, drv_len) ) { // open successfully TU_LOG_USBH(" %s opened\r\n", driver->name); // bind (associated) interfaces to found driver - for(uint8_t i=0; ibInterfaceNumber+i; // Interface number must not be used already @@ -1702,8 +1622,7 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur break; // exit driver find loop } - if ( drv_id == TOTAL_DRIVER_COUNT - 1 ) - { + if ( drv_id == TOTAL_DRIVER_COUNT - 1 ) { TU_LOG_USBH("[%u:%u] Interface %u: class = %u subclass = %u protocol = %u is not supported\r\n", dev->rhport, dev_addr, desc_itf->bInterfaceNumber, desc_itf->bInterfaceClass, desc_itf->bInterfaceSubClass, desc_itf->bInterfaceProtocol); } diff --git a/src/tusb.c b/src/tusb.c index 3ef380c83..7c86f1ca5 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -112,8 +112,7 @@ uint8_t const * tu_desc_find3(uint8_t const* desc, uint8_t const* end, uint8_t b // Endpoint Helper for both Host and Device stack //--------------------------------------------------------------------+ -bool tu_edpt_claim(tu_edpt_state_t* ep_state, osal_mutex_t mutex) -{ +bool tu_edpt_claim(tu_edpt_state_t* ep_state, osal_mutex_t mutex) { (void) mutex; // pre-check to help reducing mutex lock @@ -122,8 +121,7 @@ bool tu_edpt_claim(tu_edpt_state_t* ep_state, osal_mutex_t mutex) // can only claim the endpoint if it is not busy and not claimed yet. bool const available = (ep_state->busy == 0) && (ep_state->claimed == 0); - if (available) - { + if (available) { ep_state->claimed = 1; } @@ -132,16 +130,14 @@ bool tu_edpt_claim(tu_edpt_state_t* ep_state, osal_mutex_t mutex) return available; } -bool tu_edpt_release(tu_edpt_state_t* ep_state, osal_mutex_t mutex) -{ +bool tu_edpt_release(tu_edpt_state_t* ep_state, osal_mutex_t mutex) { (void) mutex; (void) osal_mutex_lock(mutex, OSAL_TIMEOUT_WAIT_FOREVER); // can only release the endpoint if it is claimed and not busy bool const ret = (ep_state->claimed == 1) && (ep_state->busy == 0); - if (ret) - { + if (ret) { ep_state->claimed = 0; } From 1d3969acbd1d85753c8ad085097a26dcd628afcb Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 4 Mar 2024 17:44:53 +0700 Subject: [PATCH 134/454] - usbh enumeration: move _parse_configuration_descriptor after SET_CONFIGURATION is successful - usbh: abort all pending xfer when SET_CONFIGURATION is complete - use tu_edpt_release in tuh_edpt_abort_xfer instead of usbh_edpt_release - rename _xfer_complete -> _control_xfer_complete --- src/host/usbh.c | 44 ++++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/src/host/usbh.c b/src/host/usbh.c index 407d97234..625857683 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -621,7 +621,7 @@ TU_ATTR_ALWAYS_INLINE static inline void _set_control_xfer_stage(uint8_t stage) (void) osal_mutex_unlock(_usbh_mutex); } -static void _xfer_complete(uint8_t daddr, xfer_result_t result) { +static void _control_xfer_complete(uint8_t daddr, xfer_result_t result) { TU_LOG_USBH("\r\n"); // duplicate xfer since user can execute control transfer within callback @@ -644,32 +644,32 @@ static void _xfer_complete(uint8_t daddr, xfer_result_t result) { } } -static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { +static bool usbh_control_xfer_cb (uint8_t daddr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void) ep_addr; - const uint8_t rhport = usbh_get_rhport(dev_addr); + const uint8_t rhport = usbh_get_rhport(daddr); tusb_control_request_t const * request = &_ctrl_xfer.request; if (XFER_RESULT_SUCCESS != result) { - TU_LOG_USBH("[%u:%u] Control %s, xferred_bytes = %lu\r\n", rhport, dev_addr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED", xferred_bytes); + TU_LOG_USBH("[%u:%u] Control %s, xferred_bytes = %lu\r\n", rhport, daddr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED", xferred_bytes); TU_LOG_BUF_USBH(request, 8); // terminate transfer if any stage failed - _xfer_complete(dev_addr, result); + _control_xfer_complete(daddr, result); }else { switch(_ctrl_xfer.stage) { case CONTROL_STAGE_SETUP: if (request->wLength) { // DATA stage: initial data toggle is always 1 _set_control_xfer_stage(CONTROL_STAGE_DATA); - TU_ASSERT( hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, request->bmRequestType_bit.direction), _ctrl_xfer.buffer, request->wLength) ); + TU_ASSERT( hcd_edpt_xfer(rhport, daddr, tu_edpt_addr(0, request->bmRequestType_bit.direction), _ctrl_xfer.buffer, request->wLength) ); return true; } TU_ATTR_FALLTHROUGH; case CONTROL_STAGE_DATA: if (request->wLength) { - TU_LOG_USBH("[%u:%u] Control data:\r\n", rhport, dev_addr); + TU_LOG_USBH("[%u:%u] Control data:\r\n", rhport, daddr); TU_LOG_MEM_USBH(_ctrl_xfer.buffer, xferred_bytes, 2); } @@ -677,12 +677,23 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result // ACK stage: toggle is always 1 _set_control_xfer_stage(CONTROL_STAGE_ACK); - TU_ASSERT( hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, 1-request->bmRequestType_bit.direction), NULL, 0) ); - break; + TU_ASSERT( hcd_edpt_xfer(rhport, daddr, tu_edpt_addr(0, 1 - request->bmRequestType_bit.direction), NULL, 0) ); + break; - case CONTROL_STAGE_ACK: - _xfer_complete(dev_addr, result); - break; + case CONTROL_STAGE_ACK: { + // Abort all pending transfers if SET_CONFIGURATION request + // NOTE: should we force closing all non-control endpoints in the future? + if (request->bRequest == TUSB_REQ_SET_CONFIGURATION && request->bmRequestType == 0x00) { + for(uint8_t epnum=1; epnumrhport, daddr, ep_addr)); // mark as ready and release endpoint if transfer is aborted dev->ep_status[epnum][dir].busy = false; - usbh_edpt_release(daddr, ep_addr); + tu_edpt_release(&dev->ep_status[epnum][dir], _usbh_mutex); } return true; @@ -1414,9 +1425,6 @@ static void process_enumeration(tuh_xfer_t* xfer) { } case ENUM_SET_CONFIG: - // Parse configuration & set up drivers - // Driver open aren't allowed to make any usb transfer yet - TU_ASSERT(_parse_configuration_descriptor(daddr, (tusb_desc_configuration_t*) _usbh_ctrl_buf),); TU_ASSERT(tuh_configuration_set(daddr, CONFIG_NUM, process_enumeration, ENUM_CONFIG_DRIVER),); break; @@ -1427,6 +1435,10 @@ static void process_enumeration(tuh_xfer_t* xfer) { dev->configured = 1; + // Parse configuration & set up drivers + // driver_open() must not make any usb transfer + TU_ASSERT(_parse_configuration_descriptor(daddr, (tusb_desc_configuration_t*) _usbh_ctrl_buf),); + // Start the Set Configuration process for interfaces (itf = TUSB_INDEX_INVALID_8) // Since driver can perform control transfer within its set_config, this is done asynchronously. // The process continue with next interface when class driver complete its sequence with usbh_driver_set_config_complete() From 0a2444e1003dbc042ee831e6c46a7cc9cbc9ed74 Mon Sep 17 00:00:00 2001 From: Deadman Date: Tue, 27 Feb 2024 17:04:14 +0100 Subject: [PATCH 135/454] sparkfun_samd21_mini_usb board support --- .../sparkfun_samd21_mini_usb/board.cmake | 9 ++ .../boards/sparkfun_samd21_mini_usb/board.h | 51 ++++++ .../boards/sparkfun_samd21_mini_usb/board.mk | 9 ++ .../sparkfun_samd21_mini_usb.ld | 146 ++++++++++++++++++ hw/bsp/samd21/boards/trinket_m0/board.h | 2 + hw/bsp/samd21/family.c | 18 ++- 6 files changed, 233 insertions(+), 2 deletions(-) create mode 100644 hw/bsp/samd21/boards/sparkfun_samd21_mini_usb/board.cmake create mode 100644 hw/bsp/samd21/boards/sparkfun_samd21_mini_usb/board.h create mode 100644 hw/bsp/samd21/boards/sparkfun_samd21_mini_usb/board.mk create mode 100644 hw/bsp/samd21/boards/sparkfun_samd21_mini_usb/sparkfun_samd21_mini_usb.ld diff --git a/hw/bsp/samd21/boards/sparkfun_samd21_mini_usb/board.cmake b/hw/bsp/samd21/boards/sparkfun_samd21_mini_usb/board.cmake new file mode 100644 index 000000000..c1a612936 --- /dev/null +++ b/hw/bsp/samd21/boards/sparkfun_samd21_mini_usb/board.cmake @@ -0,0 +1,9 @@ +set(JLINK_DEVICE ATSAMD21G18) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + __SAMD21G18A__ + CFG_EXAMPLE_VIDEO_READONLY + ) +endfunction() diff --git a/hw/bsp/samd21/boards/sparkfun_samd21_mini_usb/board.h b/hw/bsp/samd21/boards/sparkfun_samd21_mini_usb/board.h new file mode 100644 index 000000000..60a86d743 --- /dev/null +++ b/hw/bsp/samd21/boards/sparkfun_samd21_mini_usb/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 + +// LED +#define LED_PIN /*PA*/17 /*(D13)*/ +#define LED_STATE_ON 1 + +// Button +#define BUTTON_PIN /*PA*/14 /*(D2)*/ +#define BUTTON_STATE_ACTIVE 0 + +// UART +#define UART_SERCOM 0 +#define UART_RX_PIN /*PA*/11 /*(D0)*/ +#define UART_TX_PIN /*PA*/10 /*(D1)*/ + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/samd21/boards/sparkfun_samd21_mini_usb/board.mk b/hw/bsp/samd21/boards/sparkfun_samd21_mini_usb/board.mk new file mode 100644 index 000000000..d6c9150b3 --- /dev/null +++ b/hw/bsp/samd21/boards/sparkfun_samd21_mini_usb/board.mk @@ -0,0 +1,9 @@ +CFLAGS += -D__SAMD21G18A__ -DCFG_EXAMPLE_VIDEO_READONLY + +# All source paths should be relative to the top level. +LD_FILE = $(BOARD_PATH)/$(BOARD).ld + +# For flash-jlink target +JLINK_DEVICE = ATSAMD21G18 + +flash: flash-bossac diff --git a/hw/bsp/samd21/boards/sparkfun_samd21_mini_usb/sparkfun_samd21_mini_usb.ld b/hw/bsp/samd21/boards/sparkfun_samd21_mini_usb/sparkfun_samd21_mini_usb.ld new file mode 100644 index 000000000..f5d2ad151 --- /dev/null +++ b/hw/bsp/samd21/boards/sparkfun_samd21_mini_usb/sparkfun_samd21_mini_usb.ld @@ -0,0 +1,146 @@ +/** + * \file + * + * \brief Linker script for running in internal FLASH on the SAMD21G18A + * + * 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 + 8K, LENGTH = 0x00040000 - 8K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000-0x0004 /* 4 bytes used by bootloader to keep data between resets */ +} + +/* The stack size used by the application. NOTE: you need to adjust according to your application. */ +STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x2000; + +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 + + /* .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/samd21/boards/trinket_m0/board.h b/hw/bsp/samd21/boards/trinket_m0/board.h index 741f2a7f3..c94a3abb6 100644 --- a/hw/bsp/samd21/boards/trinket_m0/board.h +++ b/hw/bsp/samd21/boards/trinket_m0/board.h @@ -31,3 +31,5 @@ // UART #define UART_SERCOM 0 +#define UART_RX_PIN 7 +#define UART_TX_PIN 6 diff --git a/hw/bsp/samd21/family.c b/hw/bsp/samd21/family.c index ccb2c99b1..7ca20c458 100644 --- a/hw/bsp/samd21/family.c +++ b/hw/bsp/samd21/family.c @@ -172,8 +172,21 @@ uint32_t board_button_read(void) { static void uart_init(void) { #if UART_SERCOM == 0 - gpio_set_pin_function(PIN_PA06, PINMUX_PA06D_SERCOM0_PAD2); - gpio_set_pin_function(PIN_PA07, PINMUX_PA07D_SERCOM0_PAD3); + #if UART_TX_PIN == 6 + gpio_set_pin_function(PIN_PA06, PINMUX_PA06D_SERCOM0_PAD2); + #elif UART_TX_PIN == 10 + gpio_set_pin_function(PIN_PA10, PINMUX_PA10C_SERCOM0_PAD2); + #else + #error "UART_TX_PIN not supported" + #endif + + #if UART_RX_PIN == 7 + gpio_set_pin_function(PIN_PA07, PINMUX_PA07D_SERCOM0_PAD3); + #elif UART_RX_PIN == 11 + gpio_set_pin_function(PIN_PA11, PINMUX_PA11C_SERCOM0_PAD3); + #else + #error "UART_RX_PIN not supported" +#endif // setup clock (48MHz) _pm_enable_bus_clock(PM_BUS_APBC, SERCOM0); @@ -194,6 +207,7 @@ static void uart_init(void) SERCOM_USART_CTRLB_TXEN | /* tx enabled */ SERCOM_USART_CTRLB_RXEN; /* rx enabled */ + /* 115200 */ SERCOM0->USART.BAUD.reg = SERCOM_USART_BAUD_FRAC_FP(0) | SERCOM_USART_BAUD_FRAC_BAUD(26); SERCOM0->USART.CTRLA.bit.ENABLE = 1; /* activate SERCOM */ From eed37476612b6c2074cc3cdabbdef88c59822114 Mon Sep 17 00:00:00 2001 From: Camila Date: Mon, 11 Mar 2024 13:11:07 +0100 Subject: [PATCH 136/454] Changes required for SDK 3.2.0: - Define EP_ALLOCREQ - Define EP_FREEREQ - Define EP_ALLOCBUFFER - Define EP_FREEBUFFER Those were previously defined in spresense-exported-sdk, but now have been removed. --- src/portable/sony/cxd56/dcd_cxd56.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/portable/sony/cxd56/dcd_cxd56.c b/src/portable/sony/cxd56/dcd_cxd56.c index 6677891a5..9a939bc6c 100644 --- a/src/portable/sony/cxd56/dcd_cxd56.c +++ b/src/portable/sony/cxd56/dcd_cxd56.c @@ -39,6 +39,25 @@ #define CXD56_SETUP_QUEUE_DEPTH (4) #define CXD56_MAX_DATA_OUT_SIZE (64) +/* Allocate/free I/O requests. + * Should not be called from interrupt processing! + */ + +#define EP_ALLOCREQ(ep) (ep)->ops->allocreq(ep) +#define EP_FREEREQ(ep,req) (ep)->ops->freereq(ep,req) + +/* Allocate/free an I/O buffer. + * Should not be called from interrupt processing! + */ + +#ifdef CONFIG_USBDEV_DMA +# define EP_ALLOCBUFFER(ep,nb) (ep)->ops->allocbuffer(ep,nb) +# define EP_FREEBUFFER(ep,buf) (ep)->ops->freebuffer(ep,buf) +#else +# define EP_ALLOCBUFFER(ep,nb) kmm_malloc(nb) +# define EP_FREEBUFFER(ep,buf) kmm_free(buf) +#endif + OSAL_QUEUE_DEF(usbd_int_set, _setup_queue_def, CXD56_SETUP_QUEUE_DEPTH, struct usb_ctrlreq_s); struct usbdcd_driver_s From 56532321443ed1ada8c2f33bd9eb6f075da66394 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 5 Mar 2024 19:43:37 +0700 Subject: [PATCH 137/454] reformat code --- src/device/usbd.c | 306 +++++++----------- src/portable/raspberrypi/rp2040/dcd_rp2040.c | 324 ++++++++----------- src/portable/raspberrypi/rp2040/rp2040_usb.c | 167 ++++------ 3 files changed, 313 insertions(+), 484 deletions(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index be85d7769..87542e9aa 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -372,10 +372,9 @@ bool tud_inited(void) { return _usbd_rhport != RHPORT_INVALID; } -bool tud_init (uint8_t rhport) -{ +bool tud_init(uint8_t rhport) { // skip if already initialized - if ( tud_inited() ) return true; + if (tud_inited()) return true; TU_LOG_USBD("USBD init on controller %u\r\n", rhport); TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(usbd_device_t)); @@ -395,15 +394,13 @@ bool tud_init (uint8_t rhport) TU_ASSERT(_usbd_q); // Get application driver if available - if ( usbd_app_driver_get_cb ) - { + if (usbd_app_driver_get_cb) { _app_driver = usbd_app_driver_get_cb(&_app_driver_count); } // Init class drivers - for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) - { - usbd_class_driver_t const * driver = get_driver(i); + for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { + usbd_class_driver_t const* driver = get_driver(i); TU_ASSERT(driver); TU_LOG_USBD("%s init\r\n", driver->name); driver->init(); @@ -418,31 +415,26 @@ bool tud_init (uint8_t rhport) return true; } -static void configuration_reset(uint8_t rhport) -{ - for ( uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++ ) - { - usbd_class_driver_t const * driver = get_driver(i); - TU_ASSERT(driver, ); +static void configuration_reset(uint8_t rhport) { + 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 + memset(_usbd_dev.ep2drv, DRVID_INVALID, sizeof(_usbd_dev.ep2drv)); // invalid mapping } -static void usbd_reset(uint8_t rhport) -{ +static void usbd_reset(uint8_t rhport) { configuration_reset(rhport); usbd_control_reset(); } -bool tud_task_event_ready(void) -{ +bool tud_task_event_ready(void) { // Skip if stack is not initialized - if ( !tud_inited() ) return false; - + if (!tud_inited()) return false; return !osal_queue_empty(_usbd_q); } @@ -450,53 +442,44 @@ bool tud_task_event_ready(void) * This top level thread manages all device controller event and delegates events to class-specific drivers. * This should be called periodically within the mainloop or rtos thread. * - @code - int main(void) - { + int main(void) { application_init(); tusb_init(); - while(1) // the mainloop - { + while(1) { // the mainloop application_code(); tud_task(); // tinyusb device task } } - @endcode */ -void tud_task_ext(uint32_t timeout_ms, bool in_isr) -{ +void tud_task_ext(uint32_t timeout_ms, bool in_isr) { (void) in_isr; // not implemented yet // Skip if stack is not initialized - if ( !tud_inited() ) return; + if (!tud_inited()) return; // Loop until there is no more events in the queue - while (1) - { + while (1) { dcd_event_t event; - if ( !osal_queue_receive(_usbd_q, &event, timeout_ms) ) return; + if (!osal_queue_receive(_usbd_q, &event, timeout_ms)) return; #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL if (event.event_id == DCD_EVENT_SETUP_RECEIVED) TU_LOG_USBD("\r\n"); // extra line for setup TU_LOG_USBD("USBD %s ", event.event_id < DCD_EVENT_COUNT ? _usbd_event_str[event.event_id] : "CORRUPTED"); #endif - switch ( event.event_id ) - { + switch (event.event_id) { case DCD_EVENT_BUS_RESET: TU_LOG_USBD(": %s Speed\r\n", tu_str_speed[event.bus_reset.speed]); usbd_reset(event.rhport); _usbd_dev.speed = event.bus_reset.speed; - break; + break; case DCD_EVENT_UNPLUGGED: TU_LOG_USBD("\r\n"); usbd_reset(event.rhport); - - // invoke callback if (tud_umount_cb) tud_umount_cb(); - break; + break; case DCD_EVENT_SETUP_RECEIVED: TU_LOG_BUF(CFG_TUD_LOG_LEVEL, &event.setup_received, 8); @@ -508,81 +491,72 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) // mark both in & out control as free _usbd_dev.ep_status[0][TUSB_DIR_OUT].busy = 0; _usbd_dev.ep_status[0][TUSB_DIR_OUT].claimed = 0; - _usbd_dev.ep_status[0][TUSB_DIR_IN ].busy = 0; - _usbd_dev.ep_status[0][TUSB_DIR_IN ].claimed = 0; + _usbd_dev.ep_status[0][TUSB_DIR_IN].busy = 0; + _usbd_dev.ep_status[0][TUSB_DIR_IN].claimed = 0; // Process control request - if ( !process_control_request(event.rhport, &event.setup_received) ) - { + if (!process_control_request(event.rhport, &event.setup_received)) { TU_LOG_USBD(" Stall EP0\r\n"); // Failed -> stall both control endpoint IN and OUT dcd_edpt_stall(event.rhport, 0); dcd_edpt_stall(event.rhport, 0 | TUSB_DIR_IN_MASK); } - break; + break; - case DCD_EVENT_XFER_COMPLETE: - { + case DCD_EVENT_XFER_COMPLETE: { // Invoke the class callback associated with the endpoint address uint8_t const ep_addr = event.xfer_complete.ep_addr; - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const ep_dir = tu_edpt_dir(ep_addr); + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const ep_dir = tu_edpt_dir(ep_addr); TU_LOG_USBD("on EP %02X with %u bytes\r\n", ep_addr, (unsigned int) event.xfer_complete.len); _usbd_dev.ep_status[epnum][ep_dir].busy = 0; _usbd_dev.ep_status[epnum][ep_dir].claimed = 0; - if ( 0 == epnum ) - { - usbd_control_xfer_cb(event.rhport, ep_addr, (xfer_result_t) event.xfer_complete.result, event.xfer_complete - .len); - } - else - { - usbd_class_driver_t const * driver = get_driver( _usbd_dev.ep2drv[epnum][ep_dir] ); - TU_ASSERT(driver, ); + if (0 == epnum) { + usbd_control_xfer_cb(event.rhport, ep_addr, (xfer_result_t) event.xfer_complete.result, + event.xfer_complete.len); + } else { + usbd_class_driver_t const* driver = get_driver(_usbd_dev.ep2drv[epnum][ep_dir]); + TU_ASSERT(driver,); TU_LOG_USBD(" %s xfer callback\r\n", driver->name); driver->xfer_cb(event.rhport, ep_addr, (xfer_result_t) event.xfer_complete.result, event.xfer_complete.len); } + break; } - break; case DCD_EVENT_SUSPEND: // NOTE: When plugging/unplugging device, the D+/D- state are unstable and // can accidentally meet the SUSPEND condition ( Bus Idle for 3ms ), which result in a series of event // e.g suspend -> resume -> unplug/plug. Skip suspend/resume if not connected - if ( _usbd_dev.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); - }else - { + } else { TU_LOG_USBD(" Skipped\r\n"); } - break; + break; case DCD_EVENT_RESUME: - if ( _usbd_dev.connected ) - { + if (_usbd_dev.connected) { TU_LOG_USBD("\r\n"); if (tud_resume_cb) tud_resume_cb(); - }else - { + } else { TU_LOG_USBD(" Skipped\r\n"); } - break; + break; case USBD_EVENT_FUNC_CALL: TU_LOG_USBD("\r\n"); - if ( event.func_call.func ) event.func_call.func(event.func_call.param); - break; + if (event.func_call.func) event.func_call.func(event.func_call.param); + break; case DCD_EVENT_SOF: default: TU_BREAKPOINT(); - break; + break; } #if CFG_TUSB_OS != OPT_OS_NONE && CFG_TUSB_OS != OPT_OS_PICO @@ -597,8 +571,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) //--------------------------------------------------------------------+ // Helper to invoke class driver control request handler -static bool invoke_class_control(uint8_t rhport, usbd_class_driver_t const * driver, tusb_control_request_t const * request) -{ +static bool invoke_class_control(uint8_t rhport, usbd_class_driver_t const * driver, tusb_control_request_t const * request) { usbd_control_set_complete_callback(driver->control_xfer_cb); TU_LOG_USBD(" %s control request\r\n", driver->name); return driver->control_xfer_cb(rhport, CONTROL_STAGE_SETUP, request); @@ -606,15 +579,12 @@ static bool invoke_class_control(uint8_t rhport, usbd_class_driver_t const * dri // This handles the actual request and its response. // return false will cause its caller to stall control endpoint -static bool process_control_request(uint8_t rhport, tusb_control_request_t const * p_request) -{ +static bool process_control_request(uint8_t rhport, tusb_control_request_t const * p_request) { usbd_control_set_complete_callback(NULL); - TU_ASSERT(p_request->bmRequestType_bit.type < TUSB_REQ_TYPE_INVALID); // Vendor request - if ( p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_VENDOR ) - { + 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); @@ -622,19 +592,16 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const } #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL - if (TUSB_REQ_TYPE_STANDARD == p_request->bmRequestType_bit.type && p_request->bRequest <= TUSB_REQ_SYNCH_FRAME) - { + if (TUSB_REQ_TYPE_STANDARD == p_request->bmRequestType_bit.type && p_request->bRequest <= TUSB_REQ_SYNCH_FRAME) { TU_LOG_USBD(" %s", tu_str_std_request[p_request->bRequest]); if (TUSB_REQ_GET_DESCRIPTOR != p_request->bRequest) TU_LOG_USBD("\r\n"); } #endif - switch ( p_request->bmRequestType_bit.recipient ) - { + switch ( p_request->bmRequestType_bit.recipient ) { //------------- Device Requests e.g in enumeration -------------// case TUSB_REQ_RCPT_DEVICE: - if ( TUSB_REQ_TYPE_CLASS == p_request->bmRequestType_bit.type ) - { + if ( TUSB_REQ_TYPE_CLASS == p_request->bmRequestType_bit.type ) { uint8_t const itf = tu_u16_low(p_request->wIndex); TU_VERIFY(itf < TU_ARRAY_SIZE(_usbd_dev.itf2drv)); @@ -645,15 +612,13 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const return invoke_class_control(rhport, driver, p_request); } - if ( TUSB_REQ_TYPE_STANDARD != p_request->bmRequestType_bit.type ) - { + if ( TUSB_REQ_TYPE_STANDARD != p_request->bmRequestType_bit.type ) { // Non standard request is not supported TU_BREAKPOINT(); return false; } - switch ( p_request->bRequest ) - { + switch ( p_request->bRequest ) { case TUSB_REQ_SET_ADDRESS: // Depending on mcu, status phase could be sent either before or after changing device address, // or even require stack to not response with status at all @@ -664,22 +629,18 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const _usbd_dev.addressed = 1; break; - case TUSB_REQ_GET_CONFIGURATION: - { + case TUSB_REQ_GET_CONFIGURATION: { uint8_t cfg_num = _usbd_dev.cfg_num; tud_control_xfer(rhport, p_request, &cfg_num, 1); } break; - case TUSB_REQ_SET_CONFIGURATION: - { + case TUSB_REQ_SET_CONFIGURATION: { uint8_t const cfg_num = (uint8_t) p_request->wValue; // Only process if new configure is different - if (_usbd_dev.cfg_num != cfg_num) - { - if ( _usbd_dev.cfg_num ) - { + if (_usbd_dev.cfg_num != cfg_num) { + if ( _usbd_dev.cfg_num ) { // 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); @@ -694,15 +655,11 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const } // Handle the new configuration and execute the corresponding callback - if ( cfg_num ) - { + if ( cfg_num ) { // switch to new configuration if not zero TU_ASSERT( process_set_config(rhport, cfg_num) ); - if ( tud_mount_cb ) tud_mount_cb(); - } - else - { + } else { if ( tud_umount_cb ) tud_umount_cb(); } } @@ -738,15 +695,14 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const tud_control_status(rhport, p_request); break; - case TUSB_REQ_GET_STATUS: - { + case TUSB_REQ_GET_STATUS: { // Device status bit mask // - Bit 0: Self Powered // - Bit 1: Remote Wakeup enabled uint16_t status = (uint16_t) ((_usbd_dev.self_powered ? 1u : 0u) | (_usbd_dev.remote_wakeup_en ? 2u : 0u)); tud_control_xfer(rhport, p_request, &status, 2); + break; } - break; // Unknown/Unsupported request default: TU_BREAKPOINT(); return false; @@ -754,8 +710,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const break; //------------- Class/Interface Specific Request -------------// - case TUSB_REQ_RCPT_INTERFACE: - { + case TUSB_REQ_RCPT_INTERFACE: { uint8_t const itf = tu_u16_low(p_request->wIndex); TU_VERIFY(itf < TU_ARRAY_SIZE(_usbd_dev.itf2drv)); @@ -764,25 +719,21 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const // all requests to Interface (STD or Class) is forwarded to class driver. // notable requests are: GET HID REPORT DESCRIPTOR, SET_INTERFACE, GET_INTERFACE - if ( !invoke_class_control(rhport, driver, p_request) ) - { + if ( !invoke_class_control(rhport, driver, p_request) ) { // For GET_INTERFACE and SET_INTERFACE, it is mandatory to respond even if the class // driver doesn't use alternate settings or implement this TU_VERIFY(TUSB_REQ_TYPE_STANDARD == p_request->bmRequestType_bit.type); - switch(p_request->bRequest) - { + switch(p_request->bRequest) { case TUSB_REQ_GET_INTERFACE: case TUSB_REQ_SET_INTERFACE: // Clear complete callback if driver set since it can also stall the request. usbd_control_set_complete_callback(NULL); - if (TUSB_REQ_GET_INTERFACE == p_request->bRequest) - { + if (TUSB_REQ_GET_INTERFACE == p_request->bRequest) { uint8_t alternate = 0; tud_control_xfer(rhport, p_request, &alternate, 1); - }else - { + }else { tud_control_status(rhport, p_request); } break; @@ -790,54 +741,42 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const default: return false; } } + break; } - break; //------------- Endpoint Request -------------// - case TUSB_REQ_RCPT_ENDPOINT: - { + case TUSB_REQ_RCPT_ENDPOINT: { uint8_t const ep_addr = tu_u16_low(p_request->wIndex); uint8_t const ep_num = tu_edpt_number(ep_addr); uint8_t const ep_dir = tu_edpt_dir(ep_addr); TU_ASSERT(ep_num < TU_ARRAY_SIZE(_usbd_dev.ep2drv) ); - usbd_class_driver_t const * driver = get_driver(_usbd_dev.ep2drv[ep_num][ep_dir]); - if ( TUSB_REQ_TYPE_STANDARD != p_request->bmRequestType_bit.type ) - { + if ( TUSB_REQ_TYPE_STANDARD != p_request->bmRequestType_bit.type ) { // Forward class request to its driver TU_VERIFY(driver); return invoke_class_control(rhport, driver, p_request); - } - else - { + } else { // Handle STD request to endpoint - switch ( p_request->bRequest ) - { - case TUSB_REQ_GET_STATUS: - { + switch ( p_request->bRequest ) { + case TUSB_REQ_GET_STATUS: { uint16_t status = usbd_edpt_stalled(rhport, ep_addr) ? 0x0001 : 0x0000; tud_control_xfer(rhport, p_request, &status, 2); } break; case TUSB_REQ_CLEAR_FEATURE: - case TUSB_REQ_SET_FEATURE: - { - if ( TUSB_REQ_FEATURE_EDPT_HALT == p_request->wValue ) - { - if ( TUSB_REQ_CLEAR_FEATURE == p_request->bRequest ) - { + case TUSB_REQ_SET_FEATURE: { + if ( TUSB_REQ_FEATURE_EDPT_HALT == p_request->wValue ) { + if ( TUSB_REQ_CLEAR_FEATURE == p_request->bRequest ) { usbd_edpt_clear_stall(rhport, ep_addr); - }else - { + }else { usbd_edpt_stall(rhport, ep_addr); } } - if (driver) - { + if (driver) { // Some classes such as USBTMC needs to clear/re-init its buffer when receiving CLEAR_FEATURE request // We will also forward std request targeted endpoint to class drivers as well @@ -853,14 +792,18 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const break; // Unknown/Unsupported request - default: TU_BREAKPOINT(); return false; + default: + TU_BREAKPOINT(); + return false; } } } break; // Unknown recipient - default: TU_BREAKPOINT(); return false; + default: + TU_BREAKPOINT(); + return false; } return true; @@ -1185,8 +1128,7 @@ void usbd_defer_func(osal_task_func_t func, void* param, bool in_isr) { // USBD Endpoint API //--------------------------------------------------------------------+ -bool usbd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep) -{ +bool usbd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const* desc_ep) { rhport = _usbd_rhport; TU_ASSERT(tu_edpt_number(desc_ep->bEndpointAddress) < CFG_TUD_ENDPPOINT_MAX); @@ -1195,37 +1137,34 @@ bool usbd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep) return dcd_edpt_open(rhport, desc_ep); } -bool usbd_edpt_claim(uint8_t rhport, uint8_t ep_addr) -{ +bool usbd_edpt_claim(uint8_t rhport, uint8_t ep_addr) { (void) rhport; // TODO add this check later, also make sure we don't starve an out endpoint while suspending // TU_VERIFY(tud_ready()); - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); tu_edpt_state_t* ep_state = &_usbd_dev.ep_status[epnum][dir]; return tu_edpt_claim(ep_state, _usbd_mutex); } -bool usbd_edpt_release(uint8_t rhport, uint8_t ep_addr) -{ +bool usbd_edpt_release(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 epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); tu_edpt_state_t* ep_state = &_usbd_dev.ep_status[epnum][dir]; return tu_edpt_release(ep_state, _usbd_mutex); } -bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) -{ +bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) { rhport = _usbd_rhport; uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); // TODO skip ready() check for now since enumeration also use this API // TU_VERIFY(tud_ready()); @@ -1239,11 +1178,9 @@ bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t // could return and USBD task can preempt and clear the busy _usbd_dev.ep_status[epnum][dir].busy = 1; - if ( dcd_edpt_xfer(rhport, ep_addr, buffer, total_bytes) ) - { + if (dcd_edpt_xfer(rhport, ep_addr, buffer, total_bytes)) { return true; - }else - { + } else { // DCD error, mark endpoint as ready to allow next transfer _usbd_dev.ep_status[epnum][dir].busy = 0; _usbd_dev.ep_status[epnum][dir].claimed = 0; @@ -1257,12 +1194,11 @@ bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t // bytes should be written and second to keep the return value free to give back a boolean // success message. If total_bytes is too big, the FIFO will copy only what is available // into the USB buffer! -bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) -{ +bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t* ff, uint16_t total_bytes) { rhport = _usbd_rhport; uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); TU_LOG_USBD(" Queue ISO EP %02X with %u bytes ... ", ep_addr, total_bytes); @@ -1273,12 +1209,10 @@ bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16 // and usbd task can preempt and clear the busy _usbd_dev.ep_status[epnum][dir].busy = 1; - if (dcd_edpt_xfer_fifo(rhport, ep_addr, ff, total_bytes)) - { + if (dcd_edpt_xfer_fifo(rhport, ep_addr, ff, total_bytes)) { TU_LOG_USBD("OK\r\n"); return true; - }else - { + } else { // DCD error, mark endpoint as ready to allow next transfer _usbd_dev.ep_status[epnum][dir].busy = 0; _usbd_dev.ep_status[epnum][dir].claimed = 0; @@ -1288,26 +1222,23 @@ bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16 } } -bool usbd_edpt_busy(uint8_t rhport, uint8_t ep_addr) -{ +bool usbd_edpt_busy(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 dir = tu_edpt_dir(ep_addr); return _usbd_dev.ep_status[epnum][dir].busy; } -void usbd_edpt_stall(uint8_t rhport, uint8_t ep_addr) -{ +void usbd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { rhport = _usbd_rhport; uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); // only stalled if currently cleared - if ( !_usbd_dev.ep_status[epnum][dir].stalled ) - { + if (!_usbd_dev.ep_status[epnum][dir].stalled) { TU_LOG_USBD(" Stall EP %02X\r\n", ep_addr); dcd_edpt_stall(rhport, ep_addr); _usbd_dev.ep_status[epnum][dir].stalled = 1; @@ -1315,16 +1246,14 @@ void usbd_edpt_stall(uint8_t rhport, uint8_t ep_addr) } } -void usbd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) -{ +void usbd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { rhport = _usbd_rhport; uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); // only clear if currently stalled - if ( _usbd_dev.ep_status[epnum][dir].stalled ) - { + if (_usbd_dev.ep_status[epnum][dir].stalled) { TU_LOG_USBD(" Clear Stall EP %02X\r\n", ep_addr); dcd_edpt_clear_stall(rhport, ep_addr); _usbd_dev.ep_status[epnum][dir].stalled = 0; @@ -1332,31 +1261,27 @@ void usbd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) } } -bool usbd_edpt_stalled(uint8_t rhport, uint8_t ep_addr) -{ +bool usbd_edpt_stalled(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 dir = tu_edpt_dir(ep_addr); return _usbd_dev.ep_status[epnum][dir].stalled; } /** * usbd_edpt_close will disable an endpoint. - * * In progress transfers on this EP may be delivered after this call. - * */ -void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr) -{ +void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr) { 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); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); dcd_edpt_close(rhport, ep_addr); _usbd_dev.ep_status[epnum][dir].stalled = 0; @@ -1366,8 +1291,7 @@ 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, 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. @@ -1375,8 +1299,7 @@ void usbd_sof_enable(uint8_t rhport, bool en) dcd_sof_enable(rhport, en); } -bool usbd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) -{ +bool usbd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { rhport = _usbd_rhport; TU_ASSERT(dcd_edpt_iso_alloc); @@ -1385,12 +1308,11 @@ bool usbd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packe return dcd_edpt_iso_alloc(rhport, ep_addr, largest_packet_size); } -bool usbd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep) -{ +bool usbd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const* desc_ep) { rhport = _usbd_rhport; uint8_t const epnum = tu_edpt_number(desc_ep->bEndpointAddress); - uint8_t const dir = tu_edpt_dir(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); diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index e8cee73fd..ba7e9f912 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -48,7 +48,7 @@ *------------------------------------------------------------------*/ // Init these in dcd_init -static uint8_t *next_buffer_ptr; +static uint8_t* next_buffer_ptr; // USB_MAX_ENDPOINTS Endpoints, direction TUSB_DIR_OUT for out and TUSB_DIR_IN for in. static struct hw_endpoint hw_endpoints[USB_MAX_ENDPOINTS][2]; @@ -56,79 +56,70 @@ static struct hw_endpoint hw_endpoints[USB_MAX_ENDPOINTS][2]; // SOF may be used by remote wakeup as RESUME, this indicate whether SOF is actually used by usbd static bool _sof_enable = false; -TU_ATTR_ALWAYS_INLINE static inline struct hw_endpoint *hw_endpoint_get_by_num(uint8_t num, tusb_dir_t dir) -{ +TU_ATTR_ALWAYS_INLINE static inline struct hw_endpoint* hw_endpoint_get_by_num(uint8_t num, tusb_dir_t dir) { return &hw_endpoints[num][dir]; } -static struct hw_endpoint *hw_endpoint_get_by_addr(uint8_t ep_addr) -{ +static struct hw_endpoint* hw_endpoint_get_by_addr(uint8_t ep_addr) { uint8_t num = tu_edpt_number(ep_addr); tusb_dir_t dir = tu_edpt_dir(ep_addr); return hw_endpoint_get_by_num(num, dir); } -static void _hw_endpoint_alloc(struct hw_endpoint *ep, uint8_t transfer_type) -{ +static void _hw_endpoint_alloc(struct hw_endpoint* ep, uint8_t transfer_type) { // size must be multiple of 64 uint size = tu_div_ceil(ep->wMaxPacketSize, 64) * 64u; // double buffered Bulk endpoint - if ( transfer_type == TUSB_XFER_BULK ) - { + if (transfer_type == TUSB_XFER_BULK) { size *= 2u; } ep->hw_data_buf = next_buffer_ptr; next_buffer_ptr += size; - assert(((uintptr_t )next_buffer_ptr & 0b111111u) == 0); + assert(((uintptr_t) next_buffer_ptr & 0b111111u) == 0); uint dpram_offset = hw_data_offset(ep->hw_data_buf); hard_assert(hw_data_offset(next_buffer_ptr) <= USB_DPRAM_MAX); pico_info(" Allocated %d bytes at offset 0x%x (0x%p)\r\n", size, dpram_offset, ep->hw_data_buf); // Fill in endpoint control register with buffer offset - uint32_t const reg = EP_CTRL_ENABLE_BITS | ((uint)transfer_type << EP_CTRL_BUFFER_TYPE_LSB) | dpram_offset; + uint32_t const reg = EP_CTRL_ENABLE_BITS | ((uint) transfer_type << EP_CTRL_BUFFER_TYPE_LSB) | dpram_offset; *ep->endpoint_control = reg; } -static void _hw_endpoint_close(struct hw_endpoint *ep) -{ - // Clear hardware registers and then zero the struct - // Clears endpoint enable - *ep->endpoint_control = 0; - // Clears buffer available, etc - *ep->buffer_control = 0; - // Clear any endpoint state - memset(ep, 0, sizeof(struct hw_endpoint)); +static void _hw_endpoint_close(struct hw_endpoint* ep) { + // Clear hardware registers and then zero the struct + // Clears endpoint enable + *ep->endpoint_control = 0; + // Clears buffer available, etc + *ep->buffer_control = 0; + // Clear any endpoint state + memset(ep, 0, sizeof(struct hw_endpoint)); - // Reclaim buffer space if all endpoints are closed - bool reclaim_buffers = true; - for ( uint8_t i = 1; i < USB_MAX_ENDPOINTS; i++ ) - { - if (hw_endpoint_get_by_num(i, TUSB_DIR_OUT)->hw_data_buf != NULL || hw_endpoint_get_by_num(i, TUSB_DIR_IN)->hw_data_buf != NULL) - { - reclaim_buffers = false; - break; - } - } - if (reclaim_buffers) - { - next_buffer_ptr = &usb_dpram->epx_data[0]; + // Reclaim buffer space if all endpoints are closed + bool reclaim_buffers = true; + for (uint8_t i = 1; i < USB_MAX_ENDPOINTS; i++) { + if (hw_endpoint_get_by_num(i, TUSB_DIR_OUT)->hw_data_buf != NULL || + hw_endpoint_get_by_num(i, TUSB_DIR_IN)->hw_data_buf != NULL) { + reclaim_buffers = false; + break; } + } + if (reclaim_buffers) { + next_buffer_ptr = &usb_dpram->epx_data[0]; + } } -static void hw_endpoint_close(uint8_t ep_addr) -{ - struct hw_endpoint *ep = hw_endpoint_get_by_addr(ep_addr); - _hw_endpoint_close(ep); +static void hw_endpoint_close(uint8_t ep_addr) { + struct hw_endpoint* ep = hw_endpoint_get_by_addr(ep_addr); + _hw_endpoint_close(ep); } -static void hw_endpoint_init(uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t transfer_type) -{ - struct hw_endpoint *ep = hw_endpoint_get_by_addr(ep_addr); +static void hw_endpoint_init(uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t transfer_type) { + struct hw_endpoint* ep = hw_endpoint_get_by_addr(ep_addr); const uint8_t num = tu_edpt_number(ep_addr); const tusb_dir_t dir = tu_edpt_dir(ep_addr); @@ -143,35 +134,26 @@ static void hw_endpoint_init(uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t t ep->transfer_type = transfer_type; // Every endpoint has a buffer control register in dpram - if ( dir == TUSB_DIR_IN ) - { + if (dir == TUSB_DIR_IN) { ep->buffer_control = &usb_dpram->ep_buf_ctrl[num].in; - } - else - { + } else { ep->buffer_control = &usb_dpram->ep_buf_ctrl[num].out; } // Clear existing buffer control state *ep->buffer_control = 0; - if ( num == 0 ) - { + if (num == 0) { // EP0 has no endpoint control register because the buffer offsets are fixed ep->endpoint_control = NULL; // Buffer offset is fixed (also double buffered) ep->hw_data_buf = (uint8_t*) &usb_dpram->ep0_buf_a[0]; - } - else - { + } else { // Set the endpoint control register (starts at EP1, hence num-1) - if ( dir == TUSB_DIR_IN ) - { + if (dir == TUSB_DIR_IN) { ep->endpoint_control = &usb_dpram->ep_ctrl[num - 1].in; - } - else - { + } else { ep->endpoint_control = &usb_dpram->ep_ctrl[num - 1].out; } @@ -180,76 +162,65 @@ static void hw_endpoint_init(uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t t } } -static void hw_endpoint_xfer(uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) -{ - struct hw_endpoint *ep = hw_endpoint_get_by_addr(ep_addr); - hw_endpoint_xfer_start(ep, buffer, total_bytes); +static void hw_endpoint_xfer(uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) { + struct hw_endpoint* ep = hw_endpoint_get_by_addr(ep_addr); + hw_endpoint_xfer_start(ep, buffer, total_bytes); } -static void __tusb_irq_path_func(hw_handle_buff_status)(void) -{ - uint32_t remaining_buffers = usb_hw->buf_status; - pico_trace("buf_status = 0x%08lx\r\n", remaining_buffers); - uint bit = 1u; - for (uint8_t i = 0; remaining_buffers && i < USB_MAX_ENDPOINTS * 2; i++) - { - if (remaining_buffers & bit) - { - // clear this in advance - usb_hw_clear->buf_status = bit; +static void __tusb_irq_path_func(hw_handle_buff_status)(void) { + uint32_t remaining_buffers = usb_hw->buf_status; + pico_trace("buf_status = 0x%08lx\r\n", remaining_buffers); + uint bit = 1u; + for (uint8_t i = 0; remaining_buffers && i < USB_MAX_ENDPOINTS * 2; i++) { + if (remaining_buffers & bit) { + // clear this in advance + usb_hw_clear->buf_status = bit; - // IN transfer for even i, OUT transfer for odd i - struct hw_endpoint *ep = hw_endpoint_get_by_num(i >> 1u, (i & 1u) ? TUSB_DIR_OUT : TUSB_DIR_IN); + // IN transfer for even i, OUT transfer for odd i + struct hw_endpoint* ep = hw_endpoint_get_by_num(i >> 1u, (i & 1u) ? TUSB_DIR_OUT : TUSB_DIR_IN); - // Continue xfer - bool done = hw_endpoint_xfer_continue(ep); - if (done) - { - // Notify - dcd_event_xfer_complete(0, ep->ep_addr, ep->xferred_len, XFER_RESULT_SUCCESS, true); - hw_endpoint_reset_transfer(ep); - } - remaining_buffers &= ~bit; - } - bit <<= 1u; + // Continue xfer + bool done = hw_endpoint_xfer_continue(ep); + if (done) { + // Notify + dcd_event_xfer_complete(0, ep->ep_addr, ep->xferred_len, XFER_RESULT_SUCCESS, true); + hw_endpoint_reset_transfer(ep); + } + remaining_buffers &= ~bit; } + bit <<= 1u; + } } -TU_ATTR_ALWAYS_INLINE static inline void reset_ep0_pid(void) -{ - // If we have finished this transfer on EP0 set pid back to 1 for next - // setup transfer. Also clear a stall in case - uint8_t addrs[] = {0x0, 0x80}; - for (uint i = 0 ; i < TU_ARRAY_SIZE(addrs); i++) - { - struct hw_endpoint *ep = hw_endpoint_get_by_addr(addrs[i]); - ep->next_pid = 1u; - } +TU_ATTR_ALWAYS_INLINE static inline void reset_ep0_pid(void) { + // If we have finished this transfer on EP0 set pid back to 1 for next + // setup transfer. Also clear a stall in case + uint8_t addrs[] = {0x0, 0x80}; + for (uint i = 0; i < TU_ARRAY_SIZE(addrs); i++) { + struct hw_endpoint* ep = hw_endpoint_get_by_addr(addrs[i]); + ep->next_pid = 1u; + } } -static void __tusb_irq_path_func(reset_non_control_endpoints)(void) -{ +static void __tusb_irq_path_func(reset_non_control_endpoints)(void) { // Disable all non-control - for ( uint8_t i = 0; i < USB_MAX_ENDPOINTS-1; i++ ) - { + for (uint8_t i = 0; i < USB_MAX_ENDPOINTS - 1; i++) { usb_dpram->ep_ctrl[i].in = 0; usb_dpram->ep_ctrl[i].out = 0; } // clear non-control hw endpoints - tu_memclr(hw_endpoints[1], sizeof(hw_endpoints) - 2*sizeof(hw_endpoint_t)); + tu_memclr(hw_endpoints[1], sizeof(hw_endpoints) - 2 * sizeof(hw_endpoint_t)); // reclaim buffer space next_buffer_ptr = &usb_dpram->epx_data[0]; } -static void __tusb_irq_path_func(dcd_rp2040_irq)(void) -{ +static void __tusb_irq_path_func(dcd_rp2040_irq)(void) { uint32_t const status = usb_hw->ints; uint32_t handled = 0; - if ( status & USB_INTF_DEV_SOF_BITS ) - { + if (status & USB_INTF_DEV_SOF_BITS) { bool keep_sof_alive = false; handled |= USB_INTF_DEV_SOF_BITS; @@ -258,20 +229,17 @@ static void __tusb_irq_path_func(dcd_rp2040_irq)(void) // Errata 15 workaround for Device Bulk-In endpoint e15_last_sof = time_us_32(); - for ( uint8_t i = 0; i < USB_MAX_ENDPOINTS; i++ ) - { - struct hw_endpoint * ep = hw_endpoint_get_by_num(i, TUSB_DIR_IN); + for (uint8_t i = 0; i < USB_MAX_ENDPOINTS; i++) { + struct hw_endpoint* ep = hw_endpoint_get_by_num(i, TUSB_DIR_IN); // Active Bulk IN endpoint requires SOF - if ( (ep->transfer_type == TUSB_XFER_BULK) && ep->active ) - { + if ((ep->transfer_type == TUSB_XFER_BULK) && ep->active) { keep_sof_alive = true; hw_endpoint_lock_update(ep, 1); // Deferred enable? - if ( ep->pending ) - { + if (ep->pending) { ep->pending = 0; hw_endpoint_start_next_buffer(ep); } @@ -282,23 +250,21 @@ static void __tusb_irq_path_func(dcd_rp2040_irq)(void) #endif // disable SOF interrupt if it is used for RESUME in remote wakeup - if ( !keep_sof_alive && !_sof_enable ) usb_hw_clear->inte = USB_INTS_DEV_SOF_BITS; + if (!keep_sof_alive && !_sof_enable) usb_hw_clear->inte = USB_INTS_DEV_SOF_BITS; dcd_event_sof(0, usb_hw->sof_rd & USB_SOF_RD_BITS, true); } // xfer events are handled before setup req. So if a transfer completes immediately // before closing the EP, the events will be delivered in same order. - if ( status & USB_INTS_BUFF_STATUS_BITS ) - { + if (status & USB_INTS_BUFF_STATUS_BITS) { handled |= USB_INTS_BUFF_STATUS_BITS; hw_handle_buff_status(); } - if ( status & USB_INTS_SETUP_REQ_BITS ) - { + if (status & USB_INTS_SETUP_REQ_BITS) { handled |= USB_INTS_SETUP_REQ_BITS; - uint8_t const * setup = remove_volatile_cast(uint8_t const*, &usb_dpram->setup_packet); + uint8_t const* setup = remove_volatile_cast(uint8_t const*, &usb_dpram->setup_packet); // reset pid to both 1 (data and ack) reset_ep0_pid(); @@ -329,8 +295,7 @@ static void __tusb_irq_path_func(dcd_rp2040_irq)(void) #endif // SE0 for 2.5 us or more (will last at least 10ms) - if ( status & USB_INTS_BUS_RESET_BITS ) - { + if (status & USB_INTS_BUS_RESET_BITS) { pico_trace("BUS RESET\r\n"); handled |= USB_INTS_BUS_RESET_BITS; @@ -342,7 +307,7 @@ static void __tusb_irq_path_func(dcd_rp2040_irq)(void) #if TUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX // Only run enumeration workaround if pull up is enabled - if ( usb_hw->sie_ctrl & USB_SIE_CTRL_PULLUP_EN_BITS ) rp2040_usb_device_enumeration_fix(); + if (usb_hw->sie_ctrl & USB_SIE_CTRL_PULLUP_EN_BITS) rp2040_usb_device_enumeration_fix(); #endif } @@ -354,22 +319,19 @@ static void __tusb_irq_path_func(dcd_rp2040_irq)(void) * because without VBUS detection, it is impossible to tell the difference between * being disconnected and suspended. */ - if ( status & USB_INTS_DEV_SUSPEND_BITS ) - { + if (status & USB_INTS_DEV_SUSPEND_BITS) { handled |= USB_INTS_DEV_SUSPEND_BITS; dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); usb_hw_clear->sie_status = USB_SIE_STATUS_SUSPENDED_BITS; } - if ( status & USB_INTS_DEV_RESUME_FROM_HOST_BITS ) - { + if (status & USB_INTS_DEV_RESUME_FROM_HOST_BITS) { handled |= USB_INTS_DEV_RESUME_FROM_HOST_BITS; dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); usb_hw_clear->sie_status = USB_SIE_STATUS_RESUME_BITS; } - if ( status ^ handled ) - { + if (status ^ handled) { panic("Unhandled IRQ 0x%x\n", (uint) (status ^ handled)); } } @@ -390,8 +352,7 @@ static void __tusb_irq_path_func(dcd_rp2040_irq)(void) #define PICO_SHARED_IRQ_HANDLER_HIGHEST_ORDER_PRIORITY 0xff #endif -void dcd_init (uint8_t rhport) -{ +void dcd_init(uint8_t rhport) { assert(rhport == 0); // Reset hardware to default state @@ -405,7 +366,7 @@ void dcd_init (uint8_t rhport) irq_add_shared_handler(USBCTRL_IRQ, dcd_rp2040_irq, PICO_SHARED_IRQ_HANDLER_HIGHEST_ORDER_PRIORITY); // Init control endpoints - tu_memclr(hw_endpoints[0], 2*sizeof(hw_endpoint_t)); + tu_memclr(hw_endpoints[0], 2 * sizeof(hw_endpoint_t)); hw_endpoint_init(0x0, 64, TUSB_XFER_CONTROL); hw_endpoint_init(0x80, 64, TUSB_XFER_CONTROL); @@ -420,27 +381,24 @@ void dcd_init (uint8_t rhport) // for the global interrupt enable... // Note: Force VBUS detect cause disconnection not detectable usb_hw->sie_ctrl = USB_SIE_CTRL_EP0_INT_1BUF_BITS; - usb_hw->inte = USB_INTS_BUFF_STATUS_BITS | USB_INTS_BUS_RESET_BITS | USB_INTS_SETUP_REQ_BITS | - USB_INTS_DEV_SUSPEND_BITS | USB_INTS_DEV_RESUME_FROM_HOST_BITS | - (FORCE_VBUS_DETECT ? 0 : USB_INTS_DEV_CONN_DIS_BITS); + usb_hw->inte = USB_INTS_BUFF_STATUS_BITS | USB_INTS_BUS_RESET_BITS | USB_INTS_SETUP_REQ_BITS | + USB_INTS_DEV_SUSPEND_BITS | USB_INTS_DEV_RESUME_FROM_HOST_BITS | + (FORCE_VBUS_DETECT ? 0 : USB_INTS_DEV_CONN_DIS_BITS); dcd_connect(rhport); } -void dcd_int_enable(__unused uint8_t rhport) -{ - assert(rhport == 0); - irq_set_enabled(USBCTRL_IRQ, true); +void dcd_int_enable(__unused uint8_t rhport) { + assert(rhport == 0); + irq_set_enabled(USBCTRL_IRQ, true); } -void dcd_int_disable(__unused uint8_t rhport) -{ - assert(rhport == 0); - irq_set_enabled(USBCTRL_IRQ, false); +void dcd_int_disable(__unused uint8_t rhport) { + assert(rhport == 0); + irq_set_enabled(USBCTRL_IRQ, false); } -void dcd_set_address (__unused uint8_t rhport, __unused uint8_t dev_addr) -{ +void dcd_set_address(__unused uint8_t rhport, __unused uint8_t dev_addr) { assert(rhport == 0); // Can't set device address in hardware until status xfer has complete @@ -448,8 +406,7 @@ void dcd_set_address (__unused uint8_t rhport, __unused uint8_t dev_addr) hw_endpoint_xfer(0x80, NULL, 0); } -void dcd_remote_wakeup(__unused uint8_t rhport) -{ +void dcd_remote_wakeup(__unused uint8_t rhport) { pico_info("dcd_remote_wakeup %d\n", rhport); assert(rhport == 0); @@ -460,100 +417,88 @@ void dcd_remote_wakeup(__unused uint8_t rhport) } // disconnect by disabling internal pull-up resistor on D+/D- -void dcd_disconnect(__unused uint8_t rhport) -{ +void dcd_disconnect(__unused uint8_t rhport) { (void) rhport; usb_hw_clear->sie_ctrl = USB_SIE_CTRL_PULLUP_EN_BITS; } // connect by enabling internal pull-up resistor on D+/D- -void dcd_connect(__unused uint8_t rhport) -{ +void dcd_connect(__unused uint8_t rhport) { (void) rhport; usb_hw_set->sie_ctrl = USB_SIE_CTRL_PULLUP_EN_BITS; } -void dcd_sof_enable(uint8_t rhport, bool en) -{ +void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; _sof_enable = en; - if (en) - { + if (en) { usb_hw_set->inte = USB_INTS_DEV_SOF_BITS; - }else - { + } +#if !TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX + else { // Don't clear immediately if the SOF workaround is in use. // The SOF handler will conditionally disable the interrupt. -#if !TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX usb_hw_clear->inte = USB_INTS_DEV_SOF_BITS; -#endif } +#endif } /*------------------------------------------------------------------*/ /* DCD Endpoint port *------------------------------------------------------------------*/ -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 ) - { + if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && + request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && + request->bRequest == TUSB_REQ_SET_ADDRESS) { usb_hw->dev_addr_ctrl = (uint8_t) request->wValue; } } -bool dcd_edpt_open (__unused uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) -{ - assert(rhport == 0); - hw_endpoint_init(desc_edpt->bEndpointAddress, tu_edpt_packet_size(desc_edpt), desc_edpt->bmAttributes.xfer); - return true; +bool dcd_edpt_open(__unused uint8_t rhport, tusb_desc_endpoint_t const* desc_edpt) { + assert(rhport == 0); + hw_endpoint_init(desc_edpt->bEndpointAddress, tu_edpt_packet_size(desc_edpt), desc_edpt->bmAttributes.xfer); + return true; } -void dcd_edpt_close_all (uint8_t rhport) -{ +void dcd_edpt_close_all(uint8_t rhport) { (void) rhport; // may need to use EP Abort reset_non_control_endpoints(); } -bool dcd_edpt_xfer(__unused uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) -{ - assert(rhport == 0); - hw_endpoint_xfer(ep_addr, buffer, total_bytes); - return true; +bool dcd_edpt_xfer(__unused uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) { + assert(rhport == 0); + hw_endpoint_xfer(ep_addr, buffer, total_bytes); + return true; } -void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) -{ +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { (void) rhport; - if ( tu_edpt_number(ep_addr) == 0 ) - { + if (tu_edpt_number(ep_addr) == 0) { // A stall on EP0 has to be armed so it can be cleared on the next setup packet - usb_hw_set->ep_stall_arm = (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) ? USB_EP_STALL_ARM_EP0_IN_BITS : USB_EP_STALL_ARM_EP0_OUT_BITS; + usb_hw_set->ep_stall_arm = (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) ? USB_EP_STALL_ARM_EP0_IN_BITS + : USB_EP_STALL_ARM_EP0_OUT_BITS; } - struct hw_endpoint *ep = hw_endpoint_get_by_addr(ep_addr); + struct hw_endpoint* ep = hw_endpoint_get_by_addr(ep_addr); // stall and clear current pending buffer // may need to use EP_ABORT _hw_endpoint_buffer_control_set_value32(ep, USB_BUF_CTRL_STALL); } -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; - if (tu_edpt_number(ep_addr)) - { - struct hw_endpoint *ep = hw_endpoint_get_by_addr(ep_addr); + if (tu_edpt_number(ep_addr)) { + struct hw_endpoint* ep = hw_endpoint_get_by_addr(ep_addr); // clear stall also reset toggle to DATA0, ready for next transfer ep->next_pid = 0; @@ -561,16 +506,13 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) } } -void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) -{ - (void) rhport; - - pico_trace("dcd_edpt_close %02x\r\n", ep_addr); - hw_endpoint_close(ep_addr); +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { + (void) rhport; + pico_trace("dcd_edpt_close %02x\r\n", ep_addr); + hw_endpoint_close(ep_addr); } -void __tusb_irq_path_func(dcd_int_handler)(uint8_t rhport) -{ +void __tusb_irq_path_func(dcd_int_handler)(uint8_t rhport) { (void) rhport; dcd_rp2040_irq(); } diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c index a512dc34f..b5bace972 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.c +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c @@ -37,24 +37,23 @@ //--------------------------------------------------------------------+ // Direction strings for debug -const char *ep_dir_string[] = { - "out", - "in", +const char* ep_dir_string[] = { + "out", + "in", }; -static void _hw_endpoint_xfer_sync(struct hw_endpoint *ep); +static void _hw_endpoint_xfer_sync(struct hw_endpoint* ep); #if TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX - static bool e15_is_bulkin_ep(struct hw_endpoint *ep); - static bool e15_is_critical_frame_period(struct hw_endpoint *ep); + static bool e15_is_bulkin_ep(struct hw_endpoint* ep); + static bool e15_is_critical_frame_period(struct hw_endpoint* ep); #else #define e15_is_bulkin_ep(x) (false) #define e15_is_critical_frame_period(x) (false) #endif // if usb hardware is in host mode -TU_ATTR_ALWAYS_INLINE static inline bool is_host_mode(void) -{ +TU_ATTR_ALWAYS_INLINE static inline bool is_host_mode(void) { return (usb_hw->main_ctrl & USB_MAIN_CTRL_HOST_NDEVICE_BITS) ? true : false; } @@ -62,8 +61,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool is_host_mode(void) // Implementation //--------------------------------------------------------------------+ -void rp2040_usb_init(void) -{ +void rp2040_usb_init(void) { // Reset usb controller reset_block(RESETS_RESET_USBCTRL_BITS); unreset_block_wait(RESETS_RESET_USBCTRL_BITS); @@ -88,45 +86,40 @@ void rp2040_usb_init(void) TU_LOG2_INT(sizeof(hw_endpoint_t)); } -void __tusb_irq_path_func(hw_endpoint_reset_transfer)(struct hw_endpoint *ep) -{ +void __tusb_irq_path_func(hw_endpoint_reset_transfer)(struct hw_endpoint* ep) { ep->active = false; ep->remaining_len = 0; ep->xferred_len = 0; ep->user_buf = 0; } -void __tusb_irq_path_func(_hw_endpoint_buffer_control_update32)(struct hw_endpoint *ep, uint32_t and_mask, uint32_t or_mask) -{ +void __tusb_irq_path_func(_hw_endpoint_buffer_control_update32)(struct hw_endpoint* ep, uint32_t and_mask, + uint32_t or_mask) { uint32_t value = 0; - if ( and_mask ) - { + if (and_mask) { value = *ep->buffer_control & and_mask; } - if ( or_mask ) - { + if (or_mask) { value |= or_mask; - if ( or_mask & USB_BUF_CTRL_AVAIL ) - { - if ( *ep->buffer_control & USB_BUF_CTRL_AVAIL ) - { + if (or_mask & USB_BUF_CTRL_AVAIL) { + if (*ep->buffer_control & USB_BUF_CTRL_AVAIL) { panic("ep %d %s was already available", tu_edpt_number(ep->ep_addr), ep_dir_string[tu_edpt_dir(ep->ep_addr)]); } *ep->buffer_control = value & ~USB_BUF_CTRL_AVAIL; // 12 cycle delay.. (should be good for 48*12Mhz = 576Mhz) // Don't need delay in host mode as host is in charge #if !CFG_TUH_ENABLED - __asm volatile ( - "b 1f\n" - "1: b 1f\n" - "1: b 1f\n" - "1: b 1f\n" - "1: b 1f\n" - "1: b 1f\n" - "1:\n" - : : : "memory"); + __asm volatile ( + "b 1f\n" + "1: b 1f\n" + "1: b 1f\n" + "1: b 1f\n" + "1: b 1f\n" + "1: b 1f\n" + "1:\n" + : : : "memory"); #endif } } @@ -135,10 +128,9 @@ void __tusb_irq_path_func(_hw_endpoint_buffer_control_update32)(struct hw_endpoi } // prepare buffer, return buffer control -static uint32_t __tusb_irq_path_func(prepare_ep_buffer)(struct hw_endpoint *ep, uint8_t buf_id) -{ +static uint32_t __tusb_irq_path_func(prepare_ep_buffer)(struct hw_endpoint* ep, uint8_t buf_id) { uint16_t const buflen = tu_min16(ep->remaining_len, ep->wMaxPacketSize); - ep->remaining_len = (uint16_t)(ep->remaining_len - buflen); + ep->remaining_len = (uint16_t) (ep->remaining_len - buflen); uint32_t buf_ctrl = buflen | USB_BUF_CTRL_AVAIL; @@ -146,10 +138,9 @@ static uint32_t __tusb_irq_path_func(prepare_ep_buffer)(struct hw_endpoint *ep, buf_ctrl |= ep->next_pid ? USB_BUF_CTRL_DATA1_PID : USB_BUF_CTRL_DATA0_PID; ep->next_pid ^= 1u; - if ( !ep->rx ) - { + if (!ep->rx) { // Copy data from user buffer to hw buffer - memcpy(ep->hw_data_buf + buf_id*64, ep->user_buf, buflen); + memcpy(ep->hw_data_buf + buf_id * 64, ep->user_buf, buflen); ep->user_buf += buflen; // Mark as full @@ -159,8 +150,7 @@ static uint32_t __tusb_irq_path_func(prepare_ep_buffer)(struct hw_endpoint *ep, // Is this the last buffer? Only really matters for host mode. Will trigger // the trans complete irq but also stop it polling. We only really care about // trans complete for setup packets being sent - if (ep->remaining_len == 0) - { + if (ep->remaining_len == 0) { buf_ctrl |= USB_BUF_CTRL_LAST; } @@ -170,8 +160,7 @@ static uint32_t __tusb_irq_path_func(prepare_ep_buffer)(struct hw_endpoint *ep, } // Prepare buffer control register value -void __tusb_irq_path_func(hw_endpoint_start_next_buffer)(struct hw_endpoint *ep) -{ +void __tusb_irq_path_func(hw_endpoint_start_next_buffer)(struct hw_endpoint* ep) { uint32_t ep_ctrl = *ep->endpoint_control; // always compute and start with buffer 0 @@ -186,8 +175,7 @@ void __tusb_irq_path_func(hw_endpoint_start_next_buffer)(struct hw_endpoint *ep) bool const force_single = (!is_host && !tu_edpt_dir(ep->ep_addr)) || (is_host && tu_edpt_number(ep->ep_addr) != 0); - if(ep->remaining_len && !force_single) - { + if (ep->remaining_len && !force_single) { // Use buffer 1 (double buffered) if there is still data // TODO: Isochronous for buffer1 bit-field is different than CBI (control bulk, interrupt) @@ -196,8 +184,7 @@ void __tusb_irq_path_func(hw_endpoint_start_next_buffer)(struct hw_endpoint *ep) // Set endpoint control double buffered bit if needed ep_ctrl &= ~EP_CTRL_INTERRUPT_PER_BUFFER; ep_ctrl |= EP_CTRL_DOUBLE_BUFFERED_BITS | EP_CTRL_INTERRUPT_PER_DOUBLE_BUFFER; - }else - { + } else { // Single buffered since 1 is enough ep_ctrl &= ~(EP_CTRL_DOUBLE_BUFFERED_BITS | EP_CTRL_INTERRUPT_PER_DOUBLE_BUFFER); ep_ctrl |= EP_CTRL_INTERRUPT_PER_BUFFER; @@ -212,35 +199,30 @@ void __tusb_irq_path_func(hw_endpoint_start_next_buffer)(struct hw_endpoint *ep) _hw_endpoint_buffer_control_set_value32(ep, buf_ctrl); } -void hw_endpoint_xfer_start(struct hw_endpoint *ep, uint8_t *buffer, uint16_t total_len) -{ +void hw_endpoint_xfer_start(struct hw_endpoint* ep, uint8_t* buffer, uint16_t total_len) { hw_endpoint_lock_update(ep, 1); - if ( ep->active ) - { + if (ep->active) { // TODO: Is this acceptable for interrupt packets? TU_LOG(1, "WARN: starting new transfer on already active ep %d %s\r\n", tu_edpt_number(ep->ep_addr), - ep_dir_string[tu_edpt_dir(ep->ep_addr)]); + ep_dir_string[tu_edpt_dir(ep->ep_addr)]); hw_endpoint_reset_transfer(ep); } // Fill in info now that we're kicking off the hw ep->remaining_len = total_len; - ep->xferred_len = 0; - ep->active = true; - ep->user_buf = buffer; + ep->xferred_len = 0; + ep->active = true; + ep->user_buf = buffer; - if ( e15_is_bulkin_ep(ep) ) - { + if (e15_is_bulkin_ep(ep)) { usb_hw_set->inte = USB_INTS_DEV_SOF_BITS; } - if ( e15_is_critical_frame_period(ep) ) - { + if (e15_is_critical_frame_period(ep)) { ep->pending = 1; - } else - { + } else { hw_endpoint_start_next_buffer(ep); } @@ -248,34 +230,30 @@ void hw_endpoint_xfer_start(struct hw_endpoint *ep, uint8_t *buffer, uint16_t to } // sync endpoint buffer and return transferred bytes -static uint16_t __tusb_irq_path_func(sync_ep_buffer)(struct hw_endpoint *ep, uint8_t buf_id) -{ +static uint16_t __tusb_irq_path_func(sync_ep_buffer)(struct hw_endpoint* ep, uint8_t buf_id) { uint32_t buf_ctrl = _hw_endpoint_buffer_control_get_value32(ep); - if (buf_id) buf_ctrl = buf_ctrl >> 16; + if (buf_id) buf_ctrl = buf_ctrl >> 16; uint16_t xferred_bytes = buf_ctrl & USB_BUF_CTRL_LEN_MASK; - if ( !ep->rx ) - { + if (!ep->rx) { // We are continuing a transfer here. If we are TX, we have successfully // sent some data can increase the length we have sent assert(!(buf_ctrl & USB_BUF_CTRL_FULL)); - ep->xferred_len = (uint16_t)(ep->xferred_len + xferred_bytes); - }else - { + ep->xferred_len = (uint16_t) (ep->xferred_len + xferred_bytes); + } else { // If we have received some data, so can increase the length // 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); - ep->xferred_len = (uint16_t)(ep->xferred_len + xferred_bytes); + 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; } // Short packet - if (xferred_bytes < ep->wMaxPacketSize) - { + if (xferred_bytes < ep->wMaxPacketSize) { pico_trace(" Short packet on buffer %d with %u bytes\r\n", buf_id, xferred_bytes); // Reduce total length as this is last packet ep->remaining_len = 0; @@ -284,8 +262,7 @@ static uint16_t __tusb_irq_path_func(sync_ep_buffer)(struct hw_endpoint *ep, uin return xferred_bytes; } -static void __tusb_irq_path_func(_hw_endpoint_xfer_sync) (struct hw_endpoint *ep) -{ +static void __tusb_irq_path_func(_hw_endpoint_xfer_sync)(struct hw_endpoint* ep) { // Update hw endpoint struct with info from hardware // after a buff status interrupt @@ -296,14 +273,11 @@ static void __tusb_irq_path_func(_hw_endpoint_xfer_sync) (struct hw_endpoint *ep uint16_t buf0_bytes = sync_ep_buffer(ep, 0); // sync buffer 1 if double buffered - if ( (*ep->endpoint_control) & EP_CTRL_DOUBLE_BUFFERED_BITS ) - { - if (buf0_bytes == ep->wMaxPacketSize) - { + if ((*ep->endpoint_control) & EP_CTRL_DOUBLE_BUFFERED_BITS) { + if (buf0_bytes == ep->wMaxPacketSize) { // sync buffer 1 if not short packet sync_ep_buffer(ep, 1); - }else - { + } else { // short packet on buffer 0 // TODO couldn't figure out how to handle this case which happen with net_lwip_webserver example // At this time (currently trigger per 2 buffer), the buffer1 is probably filled with data from @@ -335,14 +309,13 @@ static void __tusb_irq_path_func(_hw_endpoint_xfer_sync) (struct hw_endpoint *ep } // Returns true if transfer is complete -bool __tusb_irq_path_func(hw_endpoint_xfer_continue)(struct hw_endpoint *ep) -{ +bool __tusb_irq_path_func(hw_endpoint_xfer_continue)(struct hw_endpoint* ep) { hw_endpoint_lock_update(ep, 1); // Part way through a transfer - if (!ep->active) - { - panic("Can't continue xfer on inactive ep %d %s", tu_edpt_number(ep->ep_addr), ep_dir_string[tu_edpt_dir(ep->ep_addr)]); + if (!ep->active) { + panic("Can't continue xfer on inactive ep %d %s", tu_edpt_number(ep->ep_addr), + ep_dir_string[tu_edpt_dir(ep->ep_addr)]); } // Update EP struct from hardware state @@ -350,21 +323,16 @@ bool __tusb_irq_path_func(hw_endpoint_xfer_continue)(struct hw_endpoint *ep) // Now we have synced our state with the hardware. Is there more data to transfer? // If we are done then notify tinyusb - if (ep->remaining_len == 0) - { + if (ep->remaining_len == 0) { pico_trace("Completed transfer of %d bytes on ep %d %s\r\n", ep->xferred_len, tu_edpt_number(ep->ep_addr), ep_dir_string[tu_edpt_dir(ep->ep_addr)]); // Notify caller we are done so it can notify the tinyusb stack hw_endpoint_lock_update(ep, -1); return true; - } - else - { - if ( e15_is_critical_frame_period(ep) ) - { + } else { + if (e15_is_critical_frame_period(ep)) { ep->pending = 1; - } else - { + } else { hw_endpoint_start_next_buffer(ep); } } @@ -399,16 +367,14 @@ bool __tusb_irq_path_func(hw_endpoint_xfer_continue)(struct hw_endpoint *ep) volatile uint32_t e15_last_sof = 0; // check if Errata 15 is needed for this endpoint i.e device bulk-in -static bool __tusb_irq_path_func(e15_is_bulkin_ep) (struct hw_endpoint *ep) -{ +static bool __tusb_irq_path_func(e15_is_bulkin_ep)(struct hw_endpoint* ep) { return (!is_host_mode() && tu_edpt_dir(ep->ep_addr) == TUSB_DIR_IN && ep->transfer_type == TUSB_XFER_BULK); } // check if we need to apply Errata 15 workaround : i.e // Endpoint is BULK IN and is currently in critical frame period i.e 20% of last usb frame -static bool __tusb_irq_path_func(e15_is_critical_frame_period) (struct hw_endpoint *ep) -{ +static bool __tusb_irq_path_func(e15_is_critical_frame_period)(struct hw_endpoint* ep) { TU_VERIFY(e15_is_bulkin_ep(ep)); /* Avoid the last 200us (uframe 6.5-7) of a frame, up to the EOF2 point. @@ -419,11 +385,10 @@ static bool __tusb_irq_path_func(e15_is_critical_frame_period) (struct hw_endpoi if (delta < 800 || delta > 998) { return false; } - TU_LOG(3, "Avoiding sof %lu now %lu last %lu\r\n", (usb_hw->sof_rd + 1) & USB_SOF_RD_BITS, time_us_32(), e15_last_sof); + TU_LOG(3, "Avoiding sof %lu now %lu last %lu\r\n", (usb_hw->sof_rd + 1) & USB_SOF_RD_BITS, time_us_32(), + e15_last_sof); return true; } -#endif - - +#endif // TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX #endif From 2a4b27ed336799c2b6a3d92063cf5a0c41bef172 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 11 Mar 2024 22:00:21 +0700 Subject: [PATCH 138/454] add led blinky to cdc_dual_ports example --- examples/device/cdc_dual_ports/src/main.c | 70 ++++++++++++++++------- 1 file changed, 50 insertions(+), 20 deletions(-) diff --git a/examples/device/cdc_dual_ports/src/main.c b/examples/device/cdc_dual_ports/src/main.c index 98f3ab923..1167a5d50 100644 --- a/examples/device/cdc_dual_ports/src/main.c +++ b/examples/device/cdc_dual_ports/src/main.c @@ -31,12 +31,24 @@ #include "bsp/board_api.h" #include "tusb.h" -//------------- prototypes -------------// +/* 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 void led_blinking_task(void); static void cdc_task(void); /*------------- MAIN -------------*/ -int main(void) -{ +int main(void) { board_init(); // init device stack on configured roothub port @@ -46,28 +58,23 @@ int main(void) board_init_after_tusb(); } - while (1) - { + while (1) { tud_task(); // tinyusb device task cdc_task(); + led_blinking_task(); } } // echo to either Serial0 or Serial1 // with Serial0 as all lower case, Serial1 as all upper case -static void echo_serial_port(uint8_t itf, uint8_t buf[], uint32_t count) -{ +static void echo_serial_port(uint8_t itf, uint8_t buf[], uint32_t count) { uint8_t const case_diff = 'a' - 'A'; - for(uint32_t i=0; i Date: Wed, 13 Mar 2024 11:41:58 +0700 Subject: [PATCH 139/454] - only abort ep0 if it is active - rename reset_ep0_pid() to reset_ep0() - minor update log message --- src/portable/raspberrypi/rp2040/dcd_rp2040.c | 68 ++++++++------------ src/portable/raspberrypi/rp2040/rp2040_usb.c | 35 +++------- 2 files changed, 35 insertions(+), 68 deletions(-) diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index 0e9dd84e5..5c564cb1c 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -60,7 +60,7 @@ TU_ATTR_ALWAYS_INLINE static inline struct hw_endpoint* hw_endpoint_get_by_num(u return &hw_endpoints[num][dir]; } -static struct hw_endpoint* hw_endpoint_get_by_addr(uint8_t ep_addr) { +TU_ATTR_ALWAYS_INLINE static inline struct hw_endpoint* hw_endpoint_get_by_addr(uint8_t ep_addr) { uint8_t num = tu_edpt_number(ep_addr); tusb_dir_t dir = tu_edpt_dir(ep_addr); return hw_endpoint_get_by_num(num, dir); @@ -192,47 +192,31 @@ static void __tusb_irq_path_func(hw_handle_buff_status)(void) { } } -TU_ATTR_ALWAYS_INLINE static inline void reset_ep0_pid(void) -{ - // Abort any transactions from a prior control transfer, because - // receiving SETUP doesn't reset buffer control state. This works around - // a possible USB hardware erratum. +TU_ATTR_ALWAYS_INLINE static inline void reset_ep0(void) { + // If we have finished this transfer on EP0 set pid back to 1 for next + // setup transfer. Also clear a stall in case + for (uint8_t dir = 0; dir < 2; dir++) { + struct hw_endpoint* ep = hw_endpoint_get_by_num(0, dir); + if (ep->active) { + // Abort any pending transfer from a prior control transfer per USB specs + // Due to Errata RP2040-E2: ABORT flag is only applicable for B2 and later (unusable for B0, B1). + // Which means we are not guaranteed to safely abort pending transfer on B0 and B1. + uint32_t const abort_mask = (dir ? USB_EP_ABORT_EP0_IN_BITS : USB_EP_ABORT_EP0_OUT_BITS); + if (rp2040_chip_version() >= 2) { + usb_hw_set->abort = abort_mask; + while ((usb_hw->abort_done & abort_mask) != abort_mask) {} + } - // With this workaround a race window still exists, but smaller. - // ABORT flag is unusable prior to hardware B2 (RP2040-E2), so a larger - // race window exists for B1 and earlier. - if (rp2040_chip_version() >= 2) { - usb_hw_set->abort = 0x3; - while ((usb_hw->abort_done & 0x3) != 0x3) - ; - } - // If we have finished this transfer on EP0 set pid back to 1 for next - // setup transfer. Also clear a stall in case - uint8_t addrs[] = {0x0, 0x80}; - for (uint i = 0 ; i < TU_ARRAY_SIZE(addrs); i++) - { - struct hw_endpoint *ep = hw_endpoint_get_by_addr(addrs[i]); - ep->next_pid = 1u; - // Reset the buffer control now to minimize race conditions - _hw_endpoint_buffer_control_set_value32(ep, USB_BUF_CTRL_DATA1_PID | USB_BUF_CTRL_SEL); - // Explicit delay, because the one in - // _hw_endpoint_buffer_control_set_value32 is only to set AVAILABLE - __asm volatile ( - "b 1f\n" - "1: b 1f\n" - "1: b 1f\n" - "1: b 1f\n" - "1: b 1f\n" - "1: b 1f\n" - "1:\n" - : : : "memory"); - // Make sure local ep state matches peripheral - hw_endpoint_reset_transfer(ep); - } - if (rp2040_chip_version() >= 2) { - usb_hw_clear->abort = 0x3; - usb_hw_clear->abort_done = 0x3; + _hw_endpoint_buffer_control_set_value32(ep, USB_BUF_CTRL_DATA1_PID | USB_BUF_CTRL_SEL); + hw_endpoint_reset_transfer(ep); + + if (rp2040_chip_version() >= 2) { + usb_hw_clear->abort_done = abort_mask; + usb_hw_clear->abort = abort_mask; + } } + ep->next_pid = 1u; + } } static void __tusb_irq_path_func(reset_non_control_endpoints)(void) { @@ -300,7 +284,7 @@ static void __tusb_irq_path_func(dcd_rp2040_irq)(void) { uint8_t const* setup = remove_volatile_cast(uint8_t const*, &usb_dpram->setup_packet); // reset pid to both 1 (data and ack) - reset_ep0_pid(); + reset_ep0(); // Pass setup packet to tiny usb dcd_event_setup_received(0, setup, true); @@ -388,6 +372,8 @@ static void __tusb_irq_path_func(dcd_rp2040_irq)(void) { void dcd_init(uint8_t rhport) { assert(rhport == 0); + TU_LOG(2, "Chip Version B%u\r\n", rp2040_chip_version()); + // Reset hardware to default state rp2040_usb_init(); diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c index b5bace972..1ca711c77 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.c +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c @@ -35,13 +35,6 @@ //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTOTYPE //--------------------------------------------------------------------+ - -// Direction strings for debug -const char* ep_dir_string[] = { - "out", - "in", -}; - static void _hw_endpoint_xfer_sync(struct hw_endpoint* ep); #if TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX @@ -105,22 +98,14 @@ void __tusb_irq_path_func(_hw_endpoint_buffer_control_update32)(struct hw_endpoi value |= or_mask; if (or_mask & USB_BUF_CTRL_AVAIL) { if (*ep->buffer_control & USB_BUF_CTRL_AVAIL) { - panic("ep %d %s was already available", tu_edpt_number(ep->ep_addr), ep_dir_string[tu_edpt_dir(ep->ep_addr)]); + panic("ep %02X was already available", ep->ep_addr); } *ep->buffer_control = value & ~USB_BUF_CTRL_AVAIL; - // 12 cycle delay.. (should be good for 48*12Mhz = 576Mhz) + // 4.1.2.5.1 Con-current access: 12 cycles (should be good for 48*12Mhz = 576Mhz) after write to buffer control // Don't need delay in host mode as host is in charge -#if !CFG_TUH_ENABLED - __asm volatile ( - "b 1f\n" - "1: b 1f\n" - "1: b 1f\n" - "1: b 1f\n" - "1: b 1f\n" - "1: b 1f\n" - "1:\n" - : : : "memory"); -#endif + if ( !is_host_mode()) { + busy_wait_at_least_cycles(12); + } } } @@ -204,9 +189,7 @@ void hw_endpoint_xfer_start(struct hw_endpoint* ep, uint8_t* buffer, uint16_t to if (ep->active) { // TODO: Is this acceptable for interrupt packets? - TU_LOG(1, "WARN: starting new transfer on already active ep %d %s\r\n", tu_edpt_number(ep->ep_addr), - ep_dir_string[tu_edpt_dir(ep->ep_addr)]); - + TU_LOG(1, "WARN: starting new transfer on already active ep %02X\r\n", ep->ep_addr); hw_endpoint_reset_transfer(ep); } @@ -314,8 +297,7 @@ bool __tusb_irq_path_func(hw_endpoint_xfer_continue)(struct hw_endpoint* ep) { // Part way through a transfer if (!ep->active) { - panic("Can't continue xfer on inactive ep %d %s", tu_edpt_number(ep->ep_addr), - ep_dir_string[tu_edpt_dir(ep->ep_addr)]); + panic("Can't continue xfer on inactive ep %02X", ep->ep_addr); } // Update EP struct from hardware state @@ -324,8 +306,7 @@ bool __tusb_irq_path_func(hw_endpoint_xfer_continue)(struct hw_endpoint* ep) { // Now we have synced our state with the hardware. Is there more data to transfer? // If we are done then notify tinyusb if (ep->remaining_len == 0) { - pico_trace("Completed transfer of %d bytes on ep %d %s\r\n", - ep->xferred_len, tu_edpt_number(ep->ep_addr), ep_dir_string[tu_edpt_dir(ep->ep_addr)]); + pico_trace("Completed transfer of %d bytes on ep %02X\r\n", ep->xferred_len, ep->ep_addr); // Notify caller we are done so it can notify the tinyusb stack hw_endpoint_lock_update(ep, -1); return true; From 834e2c956007709b69f5f85c426dcf51bb2abf63 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 13 Mar 2024 11:46:23 +0700 Subject: [PATCH 140/454] usbd only process last setup packet in the event queue --- .idea/.gitignore | 2 ++ src/device/usbd.c | 13 ++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/.idea/.gitignore b/.idea/.gitignore index 73f69e095..b0811f163 100644 --- a/.idea/.gitignore +++ b/.idea/.gitignore @@ -6,3 +6,5 @@ /dataSources.local.xml # Editor-based HTTP Client requests /httpRequests/ +# GitHub Copilot persisted chat sessions +/copilot/chatSessions diff --git a/src/device/usbd.c b/src/device/usbd.c index 87542e9aa..ab572e095 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -68,9 +68,9 @@ typedef struct { uint8_t remote_wakeup_support : 1; // configuration descriptor's attribute uint8_t self_powered : 1; // configuration descriptor's attribute }; - volatile uint8_t cfg_num; // current active configuration (0x00 is not configured) uint8_t speed; + volatile uint8_t setup_count; 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 @@ -378,6 +378,7 @@ bool tud_init(uint8_t rhport) { TU_LOG_USBD("USBD init on controller %u\r\n", rhport); 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)); TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(tu_edpt_stream_t)); @@ -482,7 +483,12 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) { break; case DCD_EVENT_SETUP_RECEIVED: + _usbd_dev.setup_count--; TU_LOG_BUF(CFG_TUD_LOG_LEVEL, &event.setup_received, 8); + if (_usbd_dev.setup_count) { + TU_LOG_USBD(" Skipped since there is other SETUP in queue\r\n"); + break; + } // Mark as connected after receiving 1st setup packet. // But it is easier to set it every time instead of wasting time to check then set @@ -1063,6 +1069,11 @@ TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const* event, bool in_isr) // skip osal queue for SOF in usbd task break; + case DCD_EVENT_SETUP_RECEIVED: + _usbd_dev.setup_count++; + send = true; + break; + default: send = true; break; From 5a854ef2dc03373f125b48e93accf302c2fbdd66 Mon Sep 17 00:00:00 2001 From: henneboi Date: Mon, 11 Mar 2024 13:36:25 +0100 Subject: [PATCH 141/454] dcd_stm32_fsdev.c: Fix a bug seend with stm32h5xxx when the driver is compiled with cubeide O1/O2/O3 --- .../st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h index 3f4db985d..e0df21860 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h @@ -296,6 +296,19 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_cnt(USB_TypeDef * USB { #ifdef FSDEV_BUS_32BIT (void) USBx; + volatile uint32_t count = 10; + /* + WA: few cycles for RX PMA descriptor to update + This workaround is ported from stm32h5xx_hal_pcd.h : PCD_GET_EP_RX_CNT H5 + This code fixes an issue when the code is compiled in GCC with a fast optimization(O2/O3) and device with an high frequency. + The function doesn't return the correct value. + Issue observed on Windows 10 and stm32h573i_dk and tud_task() scheduled by IT, the device is not migrated the USB device is not visible . + */ + while (count > 0U) + { + asm("NOP"); + count--; + } return (pma32[2*bEpIdx + 1] & 0x03FF0000) >> 16; #else __I uint16_t *regPtr = pcd_ep_rx_cnt_ptr(USBx, bEpIdx); From f9c85ae47b0aacd6716b671a5b6ea289b43275c0 Mon Sep 17 00:00:00 2001 From: henneboi Date: Wed, 6 Mar 2024 17:46:47 +0100 Subject: [PATCH 142/454] IAR Warning: Fixed due to an boolean operation between enum (Pa089) Warning[Pa089]: enumerated type mixed with another enumerated type ...tusb_uac2_audio.c 199 This issue stops the build if we treat warning as error --- src/device/usbd.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/device/usbd.h b/src/device/usbd.h index 3ab6c813f..cf500143a 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -421,7 +421,7 @@ 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) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_NO_SYNC | TUSB_ISO_EP_ATT_EXPLICIT_FB), U16_TO_U8S_LE(4), _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 // AUDIO simple descriptor (UAC2) for 1 microphone input // - 1 Input Terminal, 1 Feature Unit (Mute and Volume Control), 1 Output Terminal, 1 Clock Source From 9e674fa109348d97fb4280ac534be665f619a4d8 Mon Sep 17 00:00:00 2001 From: Tommie Gannert Date: Fri, 15 Mar 2024 15:02:13 +0100 Subject: [PATCH 143/454] [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; } From 5d1f6934fbbeee3238267b0444172d47033a2fd9 Mon Sep 17 00:00:00 2001 From: Li Junru Date: Thu, 14 Mar 2024 20:55:05 +0800 Subject: [PATCH 144/454] fix: uvc multiple interface support 1. fix next interface may have IAD_DESC 2. fix vs_itf can't be open on bulk mode. --- src/class/video/video_device.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index c33dfa0b0..249ced83d 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -207,6 +207,24 @@ static void const* _find_desc(void const *beg, void const *end, uint_fast8_t des return cur; } +/** Find the first descriptor of two given types + * + * @param[in] beg The head of descriptor byte array. + * @param[in] end The tail of descriptor byte array. + * @param[in] desc_type_0 The first target descriptor type. + * @param[in] desc_type_1 The second target descriptor type. + * + * @return The pointer for interface descriptor. + * @retval end did not found interface descriptor */ +static void const* _find_desc_2_type(void const *beg, void const *end, uint_fast8_t desc_type_0, uint_fast8_t desc_type_1) +{ + void const *cur = beg; + while ((cur < end) && (desc_type_0 != tu_desc_type(cur)) && (desc_type_1 != tu_desc_type(cur))) { + cur = tu_desc_next(cur); + } + return cur; +} + /** Find the first descriptor specified by the arguments * * @param[in] beg The head of descriptor byte array. @@ -233,6 +251,10 @@ static void const* _find_desc_3(void const *beg, void const *end, } /** Return the next interface descriptor which has another interface number. + * If there are multiple VC interfaces, there will be an IAD descriptor before + * the next interface descriptor. Check both the IAD descriptor and the interface + * descriptor. + * 3.1 Descriptor Layout Overview * * @param[in] beg The head of descriptor byte array. * @param[in] end The tail of descriptor byte array. @@ -245,7 +267,7 @@ static void const* _next_desc_itf(void const *beg, void const *end) uint_fast8_t itfnum = ((tusb_desc_interface_t const*)cur)->bInterfaceNumber; while ((cur < end) && (itfnum == ((tusb_desc_interface_t const*)cur)->bInterfaceNumber)) { - cur = _find_desc(tu_desc_next(cur), end, TUSB_DESC_INTERFACE); + cur = _find_desc_2_type(tu_desc_next(cur), end, TUSB_DESC_INTERFACE, TUSB_DESC_INTERFACE_ASSOCIATION); } return cur; } @@ -1216,7 +1238,7 @@ uint16_t videod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin * host may not issue set_interface so open the streaming interface here. */ uint8_t const *sbeg = (uint8_t const*)itf_desc + stm->desc.beg; uint8_t const *send = (uint8_t const*)itf_desc + stm->desc.end; - if (end == _find_desc_itf(sbeg, send, _desc_itfnum(sbeg), 1)) { + if (send == _find_desc_itf(sbeg, send, _desc_itfnum(sbeg), 1)) { TU_VERIFY(_open_vs_itf(rhport, stm, 0), 0); } } From 6352081ded448ef64d5d3285dafab684d14fd649 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 15 Mar 2024 17:58:27 +0700 Subject: [PATCH 145/454] code format --- src/tusb.c | 248 ++++++++++++++++++++--------------------------------- 1 file changed, 93 insertions(+), 155 deletions(-) diff --git a/src/tusb.c b/src/tusb.c index 7c86f1ca5..ccb2a44bf 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -43,8 +43,7 @@ // Public API //--------------------------------------------------------------------+ -bool tusb_init(void) -{ +bool tusb_init(void) { #if CFG_TUD_ENABLED && defined(TUD_OPT_RHPORT) // init device stack CFG_TUSB_RHPORTx_MODE must be defined TU_ASSERT ( tud_init(TUD_OPT_RHPORT) ); @@ -58,8 +57,7 @@ bool tusb_init(void) return true; } -bool tusb_inited(void) -{ +bool tusb_inited(void) { bool ret = false; #if CFG_TUD_ENABLED @@ -77,37 +75,30 @@ bool tusb_inited(void) // Descriptor helper //--------------------------------------------------------------------+ -uint8_t const * tu_desc_find(uint8_t const* desc, uint8_t const* end, uint8_t byte1) -{ - while(desc+1 < end) - { - if ( desc[1] == byte1 ) return desc; +uint8_t const* tu_desc_find(uint8_t const* desc, uint8_t const* end, uint8_t byte1) { + while (desc + 1 < end) { + if (desc[1] == byte1) return desc; desc += desc[DESC_OFFSET_LEN]; } return NULL; } -uint8_t const * tu_desc_find2(uint8_t const* desc, uint8_t const* end, uint8_t byte1, uint8_t byte2) -{ - while(desc+2 < end) - { - if ( desc[1] == byte1 && desc[2] == byte2) return desc; +uint8_t const* tu_desc_find2(uint8_t const* desc, uint8_t const* end, uint8_t byte1, uint8_t byte2) { + while (desc + 2 < end) { + if (desc[1] == byte1 && desc[2] == byte2) return desc; desc += desc[DESC_OFFSET_LEN]; } return NULL; } -uint8_t const * tu_desc_find3(uint8_t const* desc, uint8_t const* end, uint8_t byte1, uint8_t byte2, uint8_t byte3) -{ - while(desc+3 < end) - { +uint8_t const* tu_desc_find3(uint8_t const* desc, uint8_t const* end, uint8_t byte1, uint8_t byte2, uint8_t byte3) { + while (desc + 3 < end) { if (desc[1] == byte1 && desc[2] == byte2 && desc[3] == byte3) return desc; desc += desc[DESC_OFFSET_LEN]; } return NULL; } - //--------------------------------------------------------------------+ // Endpoint Helper for both Host and Device stack //--------------------------------------------------------------------+ @@ -126,13 +117,11 @@ bool tu_edpt_claim(tu_edpt_state_t* ep_state, osal_mutex_t mutex) { } (void) osal_mutex_unlock(mutex); - return available; } bool tu_edpt_release(tu_edpt_state_t* ep_state, osal_mutex_t mutex) { (void) mutex; - (void) osal_mutex_lock(mutex, OSAL_TIMEOUT_WAIT_FOREVER); // can only release the endpoint if it is claimed and not busy @@ -142,58 +131,49 @@ bool tu_edpt_release(tu_edpt_state_t* ep_state, osal_mutex_t mutex) { } (void) osal_mutex_unlock(mutex); - return ret; } -bool tu_edpt_validate(tusb_desc_endpoint_t const * desc_ep, tusb_speed_t speed) -{ +bool tu_edpt_validate(tusb_desc_endpoint_t const* desc_ep, tusb_speed_t speed) { uint16_t const max_packet_size = tu_edpt_packet_size(desc_ep); TU_LOG2(" Open EP %02X with Size = %u\r\n", desc_ep->bEndpointAddress, max_packet_size); - switch (desc_ep->bmAttributes.xfer) - { - case TUSB_XFER_ISOCHRONOUS: - { + switch (desc_ep->bmAttributes.xfer) { + case TUSB_XFER_ISOCHRONOUS: { uint16_t const spec_size = (speed == TUSB_SPEED_HIGH ? 1024 : 1023); TU_ASSERT(max_packet_size <= spec_size); + break; } - break; case TUSB_XFER_BULK: - if (speed == TUSB_SPEED_HIGH) - { + if (speed == TUSB_SPEED_HIGH) { // Bulk highspeed must be EXACTLY 512 TU_ASSERT(max_packet_size == 512); - }else - { + } else { // TODO Bulk fullspeed can only be 8, 16, 32, 64 TU_ASSERT(max_packet_size <= 64); } - break; + break; - case TUSB_XFER_INTERRUPT: - { + case TUSB_XFER_INTERRUPT: { uint16_t const spec_size = (speed == TUSB_SPEED_HIGH ? 1024 : 64); TU_ASSERT(max_packet_size <= spec_size); + break; } - break; - default: return false; + default: + return false; } return true; } -void tu_edpt_bind_driver(uint8_t ep2drv[][2], tusb_desc_interface_t const* desc_itf, uint16_t desc_len, uint8_t driver_id) -{ +void tu_edpt_bind_driver(uint8_t ep2drv[][2], tusb_desc_interface_t const* desc_itf, uint16_t desc_len, uint8_t driver_id) { uint8_t const* p_desc = (uint8_t const*) desc_itf; uint8_t const* desc_end = p_desc + desc_len; - while( p_desc < desc_end ) - { - if ( TUSB_DESC_ENDPOINT == tu_desc_type(p_desc) ) - { + while (p_desc < desc_end) { + if (TUSB_DESC_ENDPOINT == tu_desc_type(p_desc)) { uint8_t const ep_addr = ((tusb_desc_endpoint_t const*) p_desc)->bEndpointAddress; TU_LOG(2, " Bind EP %02x to driver id %u\r\n", ep_addr, driver_id); @@ -204,25 +184,21 @@ void tu_edpt_bind_driver(uint8_t ep2drv[][2], tusb_desc_interface_t const* desc_ } } -uint16_t tu_desc_get_interface_total_len(tusb_desc_interface_t const* desc_itf, uint8_t itf_count, uint16_t max_len) -{ +uint16_t tu_desc_get_interface_total_len(tusb_desc_interface_t const* desc_itf, uint8_t itf_count, uint16_t max_len) { uint8_t const* p_desc = (uint8_t const*) desc_itf; uint16_t len = 0; - while (itf_count--) - { + while (itf_count--) { // Next on interface desc len += tu_desc_len(desc_itf); p_desc = tu_desc_next(p_desc); - while (len < max_len) - { + while (len < max_len) { // return on IAD regardless of itf count - if ( tu_desc_type(p_desc) == TUSB_DESC_INTERFACE_ASSOCIATION ) return len; + if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE_ASSOCIATION) return len; - if ( (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE) && - ((tusb_desc_interface_t const*) p_desc)->bAlternateSetting == 0 ) - { + if ((tu_desc_type(p_desc) == TUSB_DESC_INTERFACE) && + ((tusb_desc_interface_t const*) p_desc)->bAlternateSetting == 0) { break; } @@ -239,8 +215,7 @@ 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) -{ + 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_mutex); (void) new_mutex; (void) is_tx; @@ -255,16 +230,12 @@ bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool ove return true; } -TU_ATTR_ALWAYS_INLINE static inline -bool stream_claim(tu_edpt_stream_t* s) -{ - if (s->is_host) - { +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); #endif - }else - { + } else { #if CFG_TUD_ENABLED return usbd_edpt_claim(s->rhport, s->ep_addr); #endif @@ -273,16 +244,12 @@ 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) -{ - if (s->is_host) - { +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); #endif - }else - { + } else { #if CFG_TUD_ENABLED return usbd_edpt_xfer(s->rhport, s->ep_addr, count ? s->ep_buf : NULL, count); #endif @@ -291,16 +258,12 @@ 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) -{ - if (s->is_host) - { +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); #endif - }else - { + } else { #if CFG_TUD_ENABLED return usbd_edpt_release(s->rhport, s->ep_addr); #endif @@ -313,34 +276,29 @@ 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(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(!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)); return true; } -uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t* s) -{ +uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t* s) { // skip if no data - TU_VERIFY( tu_fifo_count(&s->ff), 0 ); + TU_VERIFY(tu_fifo_count(&s->ff), 0); // Claim the endpoint - TU_VERIFY( stream_claim(s), 0 ); + TU_VERIFY(stream_claim(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 ); + if (count) { + TU_ASSERT(stream_xfer(s, count), 0); return count; - }else - { + } else { // Release endpoint since we don't make any transfer // Note: data is dropped if terminal is not connected stream_release(s); @@ -348,16 +306,14 @@ 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) -{ +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); // 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) ) - { + if ((tu_fifo_count(&s->ff) >= s->ep_packetsize) || (tu_fifo_depth(&s->ff) < s->ep_packetsize)) { tu_edpt_stream_write_xfer(s); } @@ -368,8 +324,7 @@ uint32_t tu_edpt_stream_write(tu_edpt_stream_t* s, void const *buffer, uint32_t // Stream Read //--------------------------------------------------------------------+ -uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t* s) -{ +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. @@ -384,25 +339,20 @@ uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t* s) // 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 >= s->ep_packetsize) { // multiple of packet size limit by ep bufsize - uint16_t count = (uint16_t) (available & ~(s->ep_packetsize -1)); + 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(s, count), 0); return count; - }else - { + } else { // Release endpoint since we don't make any transfer stream_release(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(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); return num_read; @@ -416,38 +366,33 @@ uint32_t tu_edpt_stream_read(tu_edpt_stream_t* s, void* buffer, uint32_t bufsize #include #if CFG_TUSB_DEBUG >= CFG_TUH_LOG_LEVEL || CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL - -char const* const tu_str_speed[] = { "Full", "Low", "High" }; -char const* const tu_str_std_request[] = -{ - "Get Status" , - "Clear Feature" , - "Reserved" , - "Set Feature" , - "Reserved" , - "Set Address" , - "Get Descriptor" , - "Set Descriptor" , - "Get Configuration" , - "Set Configuration" , - "Get Interface" , - "Set Interface" , - "Synch Frame" +char const* const tu_str_speed[] = {"Full", "Low", "High"}; +char const* const tu_str_std_request[] = { + "Get Status", + "Clear Feature", + "Reserved", + "Set Feature", + "Reserved", + "Set Address", + "Get Descriptor", + "Set Descriptor", + "Get Configuration", + "Set Configuration", + "Get Interface", + "Set Interface", + "Synch Frame" }; char const* const tu_str_xfer_result[] = { "OK", "FAILED", "STALLED", "TIMEOUT" }; - #endif -static void dump_str_line(uint8_t const* buf, uint16_t count) -{ +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 Date: Fri, 15 Mar 2024 20:39:45 +0700 Subject: [PATCH 146/454] improve uvc debug message --- src/class/video/video.h | 23 +-- src/class/video/video_device.c | 223 ++++++++++++++++---------- src/device/usbd.c | 2 +- src/portable/nordic/nrf5x/dcd_nrf5x.c | 4 +- 4 files changed, 157 insertions(+), 95 deletions(-) diff --git a/src/class/video/video.h b/src/class/video/video.h index abf1e34b9..b8a9b6369 100644 --- a/src/class/video/video.h +++ b/src/class/video/video.h @@ -160,22 +160,23 @@ typedef enum { /* A.9.1 VideoControl Interface Control Selectors */ typedef enum { VIDEO_VC_CTL_UNDEFINED = 0x00, - VIDEO_VC_CTL_VIDEO_POWER_MODE, - VIDEO_VC_CTL_REQUEST_ERROR_CODE, + VIDEO_VC_CTL_VIDEO_POWER_MODE, // 0x01 + VIDEO_VC_CTL_REQUEST_ERROR_CODE, // 0x02 } video_interface_control_selector_t; /* A.9.8 VideoStreaming Interface Control Selectors */ typedef enum { VIDEO_VS_CTL_UNDEFINED = 0x00, - VIDEO_VS_CTL_PROBE, - VIDEO_VS_CTL_COMMIT, - VIDEO_VS_CTL_STILL_PROBE, - VIDEO_VS_CTL_STILL_COMMIT, - VIDEO_VS_CTL_STILL_IMAGE_TRIGGER, - VIDEO_VS_CTL_STREAM_ERROR_CODE, - VIDEO_VS_CTL_GENERATE_KEY_FRAME, - VIDEO_VS_CTL_UPDATE_FRAME_SEGMENT, - VIDEO_VS_CTL_SYNCH_DELAY_CONTROL, + VIDEO_VS_CTL_PROBE, // 0x01 + VIDEO_VS_CTL_COMMIT, // 0x02 + VIDEO_VS_CTL_STILL_PROBE, // 0x03 + VIDEO_VS_CTL_STILL_COMMIT, // 0x04 + VIDEO_VS_CTL_STILL_IMAGE_TRIGGER, // 0x05 + VIDEO_VS_CTL_STREAM_ERROR_CODE, // 0x06 + VIDEO_VS_CTL_GENERATE_KEY_FRAME, // 0x07 + VIDEO_VS_CTL_UPDATE_FRAME_SEGMENT, // 0x08 + VIDEO_VS_CTL_SYNCH_DELAY_CONTROL, // 0x09 + } video_interface_streaming_selector_t; /* B. Terminal Types */ diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index 249ced83d..dc3f8d897 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -143,13 +143,65 @@ CFG_TUD_MEM_SECTION tu_static videod_streaming_interface_t _videod_streaming_itf tu_static uint8_t const _cap_get = 0x1u; /* support for GET */ tu_static uint8_t const _cap_get_set = 0x3u; /* support for GET and SET */ +//--------------------------------------------------------------------+ +// Debug +//--------------------------------------------------------------------+ +#if CFG_TUSB_DEBUG >= CFG_TUD_VIDEO_LOG_LEVEL + +static tu_lookup_entry_t const tu_lookup_video_request[] = { + {.key = VIDEO_REQUEST_UNDEFINED, .data = "Undefined"}, + {.key = VIDEO_REQUEST_SET_CUR, .data = "SetCur"}, + {.key = VIDEO_REQUEST_SET_CUR_ALL, .data = "SetCurAll"}, + {.key = VIDEO_REQUEST_GET_CUR, .data = "GetCur"}, + {.key = VIDEO_REQUEST_GET_MIN, .data = "GetMin"}, + {.key = VIDEO_REQUEST_GET_MAX, .data = "GetMax"}, + {.key = VIDEO_REQUEST_GET_RES, .data = "GetRes"}, + {.key = VIDEO_REQUEST_GET_LEN, .data = "GetLen"}, + {.key = VIDEO_REQUEST_GET_INFO, .data = "GetInfo"}, + {.key = VIDEO_REQUEST_GET_DEF, .data = "GetDef"}, + {.key = VIDEO_REQUEST_GET_CUR_ALL, .data = "GetCurAll"}, + {.key = VIDEO_REQUEST_GET_MIN_ALL, .data = "GetMinAll"}, + {.key = VIDEO_REQUEST_GET_MAX_ALL, .data = "GetMaxAll"}, + {.key = VIDEO_REQUEST_GET_RES_ALL, .data = "GetResAll"}, + {.key = VIDEO_REQUEST_GET_DEF_ALL, .data = "GetDefAll"}, +}; + +static tu_lookup_table_t const tu_table_video_request = { + .count = TU_ARRAY_SIZE(tu_lookup_video_request), + .items = tu_lookup_video_request +}; + +static char const* const tu_str_video_vc_control_selector[] = { + "Undefined", + "Video Power Mode", + "Request Error Code", +}; + +static char const* const tu_str_video_vs_control_selector[] = { + "Undefined", + "Probe", + "Commit", + "Still Probe", + "Still Commit", + "Still Image Trigger", + "Stream Error Code", + "Generate Key Frame", + "Update Frame Segment", + "Sync Delay", +}; + +#endif + +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ + /** Get interface number from the interface descriptor * * @param[in] desc interface descriptor * * @return bInterfaceNumber */ -static inline uint8_t _desc_itfnum(void const *desc) -{ +static inline uint8_t _desc_itfnum(void const *desc) { return ((uint8_t const*)desc)[2]; } @@ -158,8 +210,7 @@ static inline uint8_t _desc_itfnum(void const *desc) * @param[in] desc endpoint descriptor * * @return bEndpointAddress */ -static inline uint8_t _desc_ep_addr(void const *desc) -{ +static inline uint8_t _desc_ep_addr(void const *desc) { return ((uint8_t const*)desc)[2]; } @@ -169,8 +220,7 @@ static inline uint8_t _desc_ep_addr(void const *desc) * @param[in] stm_idx index number of streaming interface * * @return instance */ -static videod_streaming_interface_t* _get_instance_streaming(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) -{ +static videod_streaming_interface_t* _get_instance_streaming(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) { videod_interface_t *ctl = &_videod_itf[ctl_idx]; if (!ctl->beg) return NULL; videod_streaming_interface_t *stm = &_videod_streaming_itf[ctl->stm[stm_idx]]; @@ -178,13 +228,11 @@ static videod_streaming_interface_t* _get_instance_streaming(uint_fast8_t ctl_id return stm; } -static tusb_desc_vc_itf_t const* _get_desc_vc(videod_interface_t const *self) -{ +static tusb_desc_vc_itf_t const* _get_desc_vc(videod_interface_t const *self) { return (tusb_desc_vc_itf_t const *)(self->beg + self->cur); } -static tusb_desc_vs_itf_t const* _get_desc_vs(videod_streaming_interface_t const *self) -{ +static tusb_desc_vs_itf_t const* _get_desc_vs(videod_streaming_interface_t const *self) { if (!self->desc.cur) return NULL; uint8_t const *desc = _videod_itf[self->index_vc].beg; return (tusb_desc_vs_itf_t const*)(desc + self->desc.cur); @@ -198,8 +246,7 @@ static tusb_desc_vs_itf_t const* _get_desc_vs(videod_streaming_interface_t const * * @return The pointer for interface descriptor. * @retval end did not found interface descriptor */ -static void const* _find_desc(void const *beg, void const *end, uint_fast8_t desc_type) -{ +static void const* _find_desc(void const *beg, void const *end, uint_fast8_t desc_type) { void const *cur = beg; while ((cur < end) && (desc_type != tu_desc_type(cur))) { cur = tu_desc_next(cur); @@ -238,8 +285,7 @@ static void const* _find_desc_2_type(void const *beg, void const *end, uint_fast static void const* _find_desc_3(void const *beg, void const *end, uint_fast8_t desc_type, uint_fast8_t element_0, - uint_fast8_t element_1) -{ + uint_fast8_t element_1) { for (void const *cur = beg; cur < end; cur = _find_desc(cur, end, desc_type)) { uint8_t const *p = (uint8_t const *)cur; if ((p[2] == element_0) && (p[3] == element_1)) { @@ -261,8 +307,7 @@ static void const* _find_desc_3(void const *beg, void const *end, * * @return The pointer for interface descriptor. * @retval end did not found interface descriptor */ -static void const* _next_desc_itf(void const *beg, void const *end) -{ +static void const* _next_desc_itf(void const *beg, void const *end) { void const *cur = beg; uint_fast8_t itfnum = ((tusb_desc_interface_t const*)cur)->bInterfaceNumber; while ((cur < end) && @@ -413,8 +458,10 @@ static bool _update_streaming_parameters(videod_streaming_interface_t const *stm case VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED: param->wCompQuality = 1; /* 1 to 10000 */ break; - case VIDEO_CS_ITF_VS_FORMAT_MJPEG: + + case VIDEO_CS_ITF_VS_FORMAT_MJPEG: break; + default: return false; } @@ -435,9 +482,11 @@ static bool _update_streaming_parameters(videod_streaming_interface_t const *stm case VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED: frame_size = (uint_fast32_t)frm->wWidth * frm->wHeight * fmt->uncompressed.bBitsPerPixel / 8; break; + case VIDEO_CS_ITF_VS_FORMAT_MJPEG: frame_size = (uint_fast32_t)frm->wWidth * frm->wHeight * 16 / 8; /* YUV422 */ break; + default: break; } param->dwMaxVideoFrameSize = frame_size; @@ -478,10 +527,12 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * if (_get_desc_vs(stm)) param->bFormatIndex = _get_desc_vs(stm)->stm.bNumFormats; break; + case VIDEO_REQUEST_GET_MIN: case VIDEO_REQUEST_GET_DEF: param->bFormatIndex = 1; break; + default: return false; } /* Set the parameters determined by the format */ @@ -510,18 +561,22 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * case VIDEO_REQUEST_GET_MAX: frmnum = fmt->bNumFrameDescriptors; break; + case VIDEO_REQUEST_GET_MIN: frmnum = 1; break; + case VIDEO_REQUEST_GET_DEF: switch (fmt->bDescriptorSubType) { - case VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED: - frmnum = fmt->uncompressed.bDefaultFrameIndex; - break; - case VIDEO_CS_ITF_VS_FORMAT_MJPEG: - frmnum = fmt->mjpeg.bDefaultFrameIndex; - break; - default: return false; + case VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED: + frmnum = fmt->uncompressed.bDefaultFrameIndex; + break; + + case VIDEO_CS_ITF_VS_FORMAT_MJPEG: + frmnum = fmt->mjpeg.bDefaultFrameIndex; + break; + + default: return false; } break; default: return false; @@ -534,9 +589,11 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * case VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED: frame_size = (uint_fast32_t)frm->wWidth * frm->wHeight * fmt->uncompressed.bBitsPerPixel / 8; break; + case VIDEO_CS_ITF_VS_FORMAT_MJPEG: frame_size = (uint_fast32_t)frm->wWidth * frm->wHeight * 16 / 8; /* YUV422 */ break; + default: return false; } param->dwMaxVideoFrameSize = frame_size; @@ -552,42 +609,43 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * uint_fast32_t interval, interval_ms; switch (request) { - case VIDEO_REQUEST_GET_MAX: - { - uint_fast32_t min_interval, max_interval; - uint_fast8_t num_intervals = frm->uncompressed.bFrameIntervalType; - max_interval = num_intervals ? frm->uncompressed.dwFrameInterval[num_intervals - 1]: frm->uncompressed.dwFrameInterval[1]; - min_interval = frm->uncompressed.dwFrameInterval[0]; - interval = max_interval; - interval_ms = min_interval / 10000; - } + case VIDEO_REQUEST_GET_MAX: { + uint_fast32_t min_interval, max_interval; + uint_fast8_t num_intervals = frm->uncompressed.bFrameIntervalType; + max_interval = num_intervals ? frm->uncompressed.dwFrameInterval[num_intervals - 1]: frm->uncompressed.dwFrameInterval[1]; + min_interval = frm->uncompressed.dwFrameInterval[0]; + interval = max_interval; + interval_ms = min_interval / 10000; break; - case VIDEO_REQUEST_GET_MIN: - { - uint_fast32_t min_interval, max_interval; - uint_fast8_t num_intervals = frm->uncompressed.bFrameIntervalType; - max_interval = num_intervals ? frm->uncompressed.dwFrameInterval[num_intervals - 1]: frm->uncompressed.dwFrameInterval[1]; - min_interval = frm->uncompressed.dwFrameInterval[0]; - interval = min_interval; - interval_ms = max_interval / 10000; - } + } + + case VIDEO_REQUEST_GET_MIN: { + uint_fast32_t min_interval, max_interval; + uint_fast8_t num_intervals = frm->uncompressed.bFrameIntervalType; + max_interval = num_intervals ? frm->uncompressed.dwFrameInterval[num_intervals - 1]: frm->uncompressed.dwFrameInterval[1]; + min_interval = frm->uncompressed.dwFrameInterval[0]; + interval = min_interval; + interval_ms = max_interval / 10000; break; + } + case VIDEO_REQUEST_GET_DEF: interval = frm->uncompressed.dwDefaultFrameInterval; interval_ms = interval / 10000; break; - case VIDEO_REQUEST_GET_RES: - { - uint_fast8_t num_intervals = frm->uncompressed.bFrameIntervalType; - if (num_intervals) { - interval = 0; - interval_ms = 0; - } else { - interval = frm->uncompressed.dwFrameInterval[2]; - interval_ms = interval / 10000; - } + + case VIDEO_REQUEST_GET_RES: { + uint_fast8_t num_intervals = frm->uncompressed.bFrameIntervalType; + if (num_intervals) { + interval = 0; + interval_ms = 0; + } else { + interval = frm->uncompressed.dwFrameInterval[2]; + interval_ms = interval / 10000; } break; + } + default: return false; } param->dwFrameInterval = interval; @@ -681,8 +739,7 @@ static bool _init_vs_configuration(videod_streaming_interface_t *stm) /* initialize streaming settings */ stm->state = VS_STATE_PROBING; stm->max_payload_transfer_size = 0; - video_probe_and_commit_control_t *param = - (video_probe_and_commit_control_t *)&stm->ep_buf; + video_probe_and_commit_control_t *param = (video_probe_and_commit_control_t *)&stm->ep_buf; tu_memclr(param, sizeof(*param)); return _update_streaming_parameters(stm, param); } @@ -760,6 +817,10 @@ static uint_fast16_t _prepare_in_payload(videod_streaming_interface_t *stm) pkt_len = hdr_len + remaining; } uint_fast16_t data_len = pkt_len - hdr_len; + TU_LOG2(" prepare remain = %u, hdr_len = %u, pkt_len = %u, offset = %lu, data_len = %u\r\n", remaining, hdr_len, pkt_len, stm->offset, data_len); + if ( data_len > sizeof(stm->ep_buf) ) { + TU_BREAKPOINT(); + } memcpy(&stm->ep_buf[hdr_len], stm->buffer + stm->offset, data_len); stm->offset += data_len; remaining -= data_len; @@ -775,6 +836,7 @@ static int handle_video_ctl_std_req(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request, uint_fast8_t ctl_idx) { + TU_LOG_DRV("\r\n"); switch (request->bRequest) { case TUSB_REQ_GET_INTERFACE: if (stage == CONTROL_STAGE_SETUP) @@ -812,7 +874,10 @@ static int handle_video_ctl_cs_req(uint8_t rhport, uint8_t stage, videod_interface_t *self = &_videod_itf[ctl_idx]; /* 4.2.1 Interface Control Request */ - switch (TU_U16_HIGH(request->wValue)) { + uint8_t const ctrl_sel = TU_U16_HIGH(request->wValue); + TU_LOG_DRV("%s_Control(%s)\r\n", tu_str_video_vc_control_selector[ctrl_sel], tu_lookup_find(&tu_table_video_request, request->bRequest)); + + switch (ctrl_sel) { case VIDEO_VC_CTL_VIDEO_POWER_MODE: switch (request->bRequest) { case VIDEO_REQUEST_SET_CUR: @@ -876,19 +941,19 @@ static int handle_video_ctl_req(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request, uint_fast8_t ctl_idx) { - uint_fast8_t entity_id; switch (request->bmRequestType_bit.type) { case TUSB_REQ_TYPE_STANDARD: return handle_video_ctl_std_req(rhport, stage, request, ctl_idx); - case TUSB_REQ_TYPE_CLASS: - entity_id = TU_U16_HIGH(request->wIndex); + case TUSB_REQ_TYPE_CLASS: { + uint_fast8_t entity_id = TU_U16_HIGH(request->wIndex); if (!entity_id) { return handle_video_ctl_cs_req(rhport, stage, request, ctl_idx); } else { TU_VERIFY(_find_desc_entity(_get_desc_vc(&_videod_itf[ctl_idx]), entity_id), VIDEO_ERROR_INVALID_REQUEST); return VIDEO_ERROR_NONE; } + } default: return VIDEO_ERROR_INVALID_REQUEST; @@ -899,6 +964,7 @@ static int handle_video_stm_std_req(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request, uint_fast8_t stm_idx) { + TU_LOG_DRV("\r\n"); videod_streaming_interface_t *self = &_videod_streaming_itf[stm_idx]; switch (request->bRequest) { case TUSB_REQ_GET_INTERFACE: @@ -914,8 +980,7 @@ static int handle_video_stm_std_req(uint8_t rhport, uint8_t stage, return VIDEO_ERROR_NONE; case TUSB_REQ_SET_INTERFACE: - if (stage == CONTROL_STAGE_SETUP) - { + if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(_open_vs_itf(rhport, self, request->wValue), VIDEO_ERROR_UNKNOWN); tud_control_status(rhport, request); } @@ -929,26 +994,26 @@ static int handle_video_stm_std_req(uint8_t rhport, uint8_t stage, static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request, - uint_fast8_t stm_idx) -{ + uint_fast8_t stm_idx) { (void)rhport; videod_streaming_interface_t *self = &_videod_streaming_itf[stm_idx]; + uint8_t const ctrl_sel = TU_U16_HIGH(request->wValue); + TU_LOG_DRV("%s_Control(%s)\r\n", tu_str_video_vs_control_selector[ctrl_sel], tu_lookup_find(&tu_table_video_request, request->bRequest)); + /* 4.2.1 Interface Control Request */ - switch (TU_U16_HIGH(request->wValue)) { + switch (ctrl_sel) { case VIDEO_VS_CTL_STREAM_ERROR_CODE: switch (request->bRequest) { case VIDEO_REQUEST_GET_CUR: - if (stage == CONTROL_STAGE_SETUP) - { + if (stage == CONTROL_STAGE_SETUP) { /* TODO */ TU_VERIFY(tud_control_xfer(rhport, request, &self->error_code, sizeof(uint8_t)), VIDEO_ERROR_UNKNOWN); } return VIDEO_ERROR_NONE; case VIDEO_REQUEST_GET_INFO: - if (stage == CONTROL_STAGE_SETUP) - { + if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(tud_control_xfer(rhport, request, (uint8_t*)(uintptr_t) &_cap_get, sizeof(_cap_get)), VIDEO_ERROR_UNKNOWN); } return VIDEO_ERROR_NONE; @@ -962,6 +1027,7 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage, self->state = VS_STATE_PROBING; _init_vs_configuration(self); } + switch (request->bRequest) { case VIDEO_REQUEST_SET_CUR: if (stage == CONTROL_STAGE_SETUP) { @@ -975,8 +1041,7 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage, return VIDEO_ERROR_NONE; case VIDEO_REQUEST_GET_CUR: - if (stage == CONTROL_STAGE_SETUP) - { + if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(request->wLength, VIDEO_ERROR_UNKNOWN); TU_VERIFY(tud_control_xfer(rhport, request, self->ep_buf, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN); } @@ -986,8 +1051,7 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage, case VIDEO_REQUEST_GET_MAX: case VIDEO_REQUEST_GET_RES: case VIDEO_REQUEST_GET_DEF: - if (stage == CONTROL_STAGE_SETUP) - { + if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(request->wLength, VIDEO_ERROR_UNKNOWN); video_probe_and_commit_control_t tmp; tmp = *(video_probe_and_commit_control_t*)&self->ep_buf; @@ -997,8 +1061,7 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage, return VIDEO_ERROR_NONE; case VIDEO_REQUEST_GET_LEN: - if (stage == CONTROL_STAGE_SETUP) - { + if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(2 == request->wLength, VIDEO_ERROR_UNKNOWN); uint16_t len = sizeof(video_probe_and_commit_control_t); TU_VERIFY(tud_control_xfer(rhport, request, (uint8_t*)&len, sizeof(len)), VIDEO_ERROR_UNKNOWN); @@ -1006,8 +1069,7 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage, return VIDEO_ERROR_NONE; case VIDEO_REQUEST_GET_INFO: - if (stage == CONTROL_STAGE_SETUP) - { + if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(1 == request->wLength, VIDEO_ERROR_UNKNOWN); TU_VERIFY(tud_control_xfer(rhport, request, (uint8_t*)(uintptr_t)&_cap_get_set, sizeof(_cap_get_set)), VIDEO_ERROR_UNKNOWN); } @@ -1046,16 +1108,14 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage, return VIDEO_ERROR_NONE; case VIDEO_REQUEST_GET_CUR: - if (stage == CONTROL_STAGE_SETUP) - { + if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(request->wLength, VIDEO_ERROR_UNKNOWN); TU_VERIFY(tud_control_xfer(rhport, request, self->ep_buf, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN); } return VIDEO_ERROR_NONE; case VIDEO_REQUEST_GET_LEN: - if (stage == CONTROL_STAGE_SETUP) - { + if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(2 == request->wLength, VIDEO_ERROR_UNKNOWN); uint16_t len = sizeof(video_probe_and_commit_control_t); TU_VERIFY(tud_control_xfer(rhport, request, (uint8_t*)&len, sizeof(len)), VIDEO_ERROR_UNKNOWN); @@ -1063,8 +1123,7 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage, return VIDEO_ERROR_NONE; case VIDEO_REQUEST_GET_INFO: - if (stage == CONTROL_STAGE_SETUP) - { + if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(1 == request->wLength, VIDEO_ERROR_UNKNOWN); TU_VERIFY(tud_control_xfer(rhport, request, (uint8_t*)(uintptr_t) &_cap_get_set, sizeof(_cap_get_set)), VIDEO_ERROR_UNKNOWN); } @@ -1264,6 +1323,7 @@ bool videod_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_ } if (itf < CFG_TUD_VIDEO) { + TU_LOG_DRV(" VC[%d]: ", itf); err = handle_video_ctl_req(rhport, stage, request, itf); _videod_itf[itf].error_code = (uint8_t)err; if (err) return false; @@ -1279,6 +1339,7 @@ bool videod_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_ } if (itf < CFG_TUD_VIDEO_STREAMING) { + TU_LOG_DRV(" VS[%d]: ", itf); err = handle_video_stm_req(rhport, stage, request, itf); _videod_streaming_itf[itf].error_code = (uint8_t)err; if (err) return false; diff --git a/src/device/usbd.c b/src/device/usbd.c index ab572e095..96d0b698b 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -319,7 +319,7 @@ void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback) { for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { usbd_class_driver_t const* driver = get_driver(i); if (driver && driver->control_xfer_cb == callback) { - TU_LOG_USBD(" %s control complete\r\n", driver->name); + TU_LOG_USBD("%s control complete\r\n", driver->name); return; } } diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index 841cda752..80a285ef0 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -246,7 +246,7 @@ static void xact_in_dma(uint8_t epnum) //--------------------------------------------------------------------+ void dcd_init (uint8_t rhport) { - TU_LOG1("dcd init\r\n"); + TU_LOG2("dcd init\r\n"); (void) rhport; } @@ -685,7 +685,7 @@ void dcd_int_handler(uint8_t rhport) if ( int_status & USBD_INTEN_USBEVENT_Msk ) { - TU_LOG(2, "EVENTCAUSE = 0x%04lX\r\n", NRF_USBD->EVENTCAUSE); + TU_LOG(3, "EVENTCAUSE = 0x%04lX\r\n", NRF_USBD->EVENTCAUSE); enum { EVT_CAUSE_MASK = USBD_EVENTCAUSE_SUSPEND_Msk | USBD_EVENTCAUSE_RESUME_Msk | USBD_EVENTCAUSE_USBWUALLOWED_Msk | USBD_EVENTCAUSE_ISOOUTCRC_Msk }; uint32_t const evt_cause = NRF_USBD->EVENTCAUSE & EVT_CAUSE_MASK; From ff12544c9ac1f61c5d25d58608f16f5991e9f776 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 20 Mar 2024 22:45:46 +0700 Subject: [PATCH 147/454] added dedicate buffer for probe commit payload --- src/class/video/video_device.c | 45 +++++++++++++--------------------- 1 file changed, 17 insertions(+), 28 deletions(-) diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index dc3f8d897..5306356ba 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -114,6 +114,8 @@ typedef struct TU_ATTR_PACKED { uint32_t max_payload_transfer_size; uint8_t error_code;/* error code */ uint8_t state; /* 0:probing 1:committed 2:streaming */ + + video_probe_and_commit_control_t probe_commit_payload; /* Probe and Commit control */ /*------------- From this point, data is not cleared by bus reset -------------*/ CFG_TUSB_MEM_ALIGN uint8_t ep_buf[CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE]; /* EP transfer buffer for streaming */ } videod_streaming_interface_t; @@ -734,12 +736,11 @@ static bool _open_vc_itf(uint8_t rhport, videod_interface_t *self, uint_fast8_t return true; } -static bool _init_vs_configuration(videod_streaming_interface_t *stm) -{ +static bool _init_vs_configuration(videod_streaming_interface_t *stm) { /* initialize streaming settings */ stm->state = VS_STATE_PROBING; stm->max_payload_transfer_size = 0; - video_probe_and_commit_control_t *param = (video_probe_and_commit_control_t *)&stm->ep_buf; + video_probe_and_commit_control_t *param = &stm->probe_commit_payload; tu_memclr(param, sizeof(*param)); return _update_streaming_parameters(stm, param); } @@ -816,11 +817,8 @@ static uint_fast16_t _prepare_in_payload(videod_streaming_interface_t *stm) if (hdr_len + remaining < pkt_len) { pkt_len = hdr_len + remaining; } + TU_ASSERT(pkt_len >= hdr_len); uint_fast16_t data_len = pkt_len - hdr_len; - TU_LOG2(" prepare remain = %u, hdr_len = %u, pkt_len = %u, offset = %lu, data_len = %u\r\n", remaining, hdr_len, pkt_len, stm->offset, data_len); - if ( data_len > sizeof(stm->ep_buf) ) { - TU_BREAKPOINT(); - } memcpy(&stm->ep_buf[hdr_len], stm->buffer + stm->offset, data_len); stm->offset += data_len; remaining -= data_len; @@ -1025,17 +1023,15 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage, case VIDEO_VS_CTL_PROBE: if (self->state != VS_STATE_PROBING) { self->state = VS_STATE_PROBING; - _init_vs_configuration(self); } switch (request->bRequest) { case VIDEO_REQUEST_SET_CUR: if (stage == CONTROL_STAGE_SETUP) { - TU_VERIFY(sizeof(video_probe_and_commit_control_t) >= request->wLength, VIDEO_ERROR_UNKNOWN); - TU_VERIFY(tud_control_xfer(rhport, request, self->ep_buf, sizeof(video_probe_and_commit_control_t)), + TU_VERIFY(tud_control_xfer(rhport, request, &self->probe_commit_payload, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN); } else if (stage == CONTROL_STAGE_DATA) { - TU_VERIFY(_update_streaming_parameters(self, (video_probe_and_commit_control_t*)self->ep_buf), + TU_VERIFY(_update_streaming_parameters(self, &self->probe_commit_payload), VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE); } return VIDEO_ERROR_NONE; @@ -1043,7 +1039,7 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage, case VIDEO_REQUEST_GET_CUR: if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(request->wLength, VIDEO_ERROR_UNKNOWN); - TU_VERIFY(tud_control_xfer(rhport, request, self->ep_buf, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN); + TU_VERIFY(tud_control_xfer(rhport, request, &self->probe_commit_payload, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN); } return VIDEO_ERROR_NONE; @@ -1053,8 +1049,7 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage, case VIDEO_REQUEST_GET_DEF: if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(request->wLength, VIDEO_ERROR_UNKNOWN); - video_probe_and_commit_control_t tmp; - tmp = *(video_probe_and_commit_control_t*)&self->ep_buf; + video_probe_and_commit_control_t tmp = self->probe_commit_payload; TU_VERIFY(_negotiate_streaming_parameters(self, request->bRequest, &tmp), VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE); TU_VERIFY(tud_control_xfer(rhport, request, &tmp, sizeof(tmp)), VIDEO_ERROR_UNKNOWN); } @@ -1083,10 +1078,9 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage, switch (request->bRequest) { case VIDEO_REQUEST_SET_CUR: if (stage == CONTROL_STAGE_SETUP) { - TU_VERIFY(sizeof(video_probe_and_commit_control_t) >= request->wLength, VIDEO_ERROR_UNKNOWN); - TU_VERIFY(tud_control_xfer(rhport, request, self->ep_buf, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN); + TU_VERIFY(tud_control_xfer(rhport, request, &self->probe_commit_payload, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN); } else if (stage == CONTROL_STAGE_DATA) { - video_probe_and_commit_control_t *param = (video_probe_and_commit_control_t*)self->ep_buf; + video_probe_and_commit_control_t *param = &self->probe_commit_payload; TU_VERIFY(_update_streaming_parameters(self, param), VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE); /* Set the negotiated value */ self->max_payload_transfer_size = param->dwMaxPayloadTransferSize; @@ -1110,7 +1104,7 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage, case VIDEO_REQUEST_GET_CUR: if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(request->wLength, VIDEO_ERROR_UNKNOWN); - TU_VERIFY(tud_control_xfer(rhport, request, self->ep_buf, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN); + TU_VERIFY(tud_control_xfer(rhport, request, &self->probe_commit_payload, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN); } return VIDEO_ERROR_NONE; @@ -1224,8 +1218,7 @@ bool tud_video_n_frame_xfer(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, void *bu //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ -void videod_init(void) -{ +void videod_init(void) { for (uint_fast8_t i = 0; i < CFG_TUD_VIDEO; ++i) { videod_interface_t* ctl = &_videod_itf[i]; tu_memclr(ctl, sizeof(*ctl)); @@ -1236,8 +1229,7 @@ void videod_init(void) } } -void videod_reset(uint8_t rhport) -{ +void videod_reset(uint8_t rhport) { (void) rhport; for (uint_fast8_t i = 0; i < CFG_TUD_VIDEO; ++i) { videod_interface_t* ctl = &_videod_itf[i]; @@ -1249,8 +1241,7 @@ void videod_reset(uint8_t rhport) } } -uint16_t videod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) -{ +uint16_t videod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) { TU_VERIFY((TUSB_CLASS_VIDEO == itf_desc->bInterfaceClass) && (VIDEO_SUBCLASS_CONTROL == itf_desc->bInterfaceSubClass) && (VIDEO_ITF_PROTOCOL_15 == itf_desc->bInterfaceProtocol), 0); @@ -1309,8 +1300,7 @@ uint16_t videod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin // 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 videod_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) -{ +bool videod_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) { int err; TU_VERIFY(request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE); uint_fast8_t itfnum = tu_u16_low(request->wIndex); @@ -1348,8 +1338,7 @@ bool videod_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_ return false; } -bool videod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) -{ +bool videod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void)result; (void)xferred_bytes; /* find streaming handle */ From 61a31db8ecf66460e4888aef7915da66d98964d0 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 20 Mar 2024 15:20:24 -0700 Subject: [PATCH 148/454] Tweaks for ESP-IDF 5.2.1 --- src/portable/espressif/esp32sx/dcd_esp32sx.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/portable/espressif/esp32sx/dcd_esp32sx.c b/src/portable/espressif/esp32sx/dcd_esp32sx.c index 1fcfb6241..bfc0baa56 100644 --- a/src/portable/espressif/esp32sx/dcd_esp32sx.c +++ b/src/portable/espressif/esp32sx/dcd_esp32sx.c @@ -31,16 +31,26 @@ #if (((CFG_TUSB_MCU == OPT_MCU_ESP32S2) || (CFG_TUSB_MCU == OPT_MCU_ESP32S3)) && CFG_TUD_ENABLED) // Espressif -#include "freertos/xtensa_api.h" +#include "xtensa_api.h" #include "esp_intr_alloc.h" #include "esp_log.h" #include "soc/dport_reg.h" #include "soc/gpio_sig_map.h" #include "soc/usb_periph.h" +#include "soc/usb_reg.h" +#include "soc/usb_struct.h" #include "soc/periph_defs.h" // for interrupt source #include "device/dcd.h" +#ifndef USB_OUT_EP_NUM +#define USB_OUT_EP_NUM ((int) (sizeof(USB0.out_ep_reg) / sizeof(USB0.out_ep_reg[0]))) +#endif + +#ifndef USB_IN_EP_NUM +#define USB_IN_EP_NUM ((int) (sizeof(USB0.in_ep_reg) / sizeof(USB0.in_ep_reg[0]))) +#endif + // Max number of bi-directional endpoints including EP0 // Note: ESP32S2 specs say there are only up to 5 IN active endpoints include EP0 // We should probably prohibit enabling Endpoint IN > 4 (not done yet) From 08b09926a4f33d94b15d7e87b88b1b9a14b95388 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 22 Mar 2024 11:12:40 +0700 Subject: [PATCH 149/454] add note for max3421e is not signal compatible with pca10056/95 --- hw/bsp/nrf/boards/pca10056/board.h | 11 ++++++----- hw/bsp/nrf/boards/pca10095/board.h | 11 ++++++----- hw/bsp/nrf/family.c | 15 +-------------- 3 files changed, 13 insertions(+), 24 deletions(-) diff --git a/hw/bsp/nrf/boards/pca10056/board.h b/hw/bsp/nrf/boards/pca10056/board.h index 9459e7911..24d3faa65 100644 --- a/hw/bsp/nrf/boards/pca10056/board.h +++ b/hw/bsp/nrf/boards/pca10056/board.h @@ -46,11 +46,12 @@ #define UART_TX_PIN 6 // SPI for USB host shield -#define MAX3421_SCK_PIN _PINNUM(1, 15) -#define MAX3421_MOSI_PIN _PINNUM(1, 13) -#define MAX3421_MISO_PIN _PINNUM(1, 14) -#define MAX3421_CS_PIN _PINNUM(1, 12) -#define MAX3421_INTR_PIN _PINNUM(1, 11) +// Pin is correct but not working probably due to signal incompatible (1.8V 3v3) with MAC3421E !? +//#define MAX3421_SCK_PIN _PINNUM(1, 15) +//#define MAX3421_MOSI_PIN _PINNUM(1, 13) +//#define MAX3421_MISO_PIN _PINNUM(1, 14) +//#define MAX3421_CS_PIN _PINNUM(1, 12) +//#define MAX3421_INTR_PIN _PINNUM(1, 11) #ifdef __cplusplus } diff --git a/hw/bsp/nrf/boards/pca10095/board.h b/hw/bsp/nrf/boards/pca10095/board.h index 7437dad48..846c2ee5b 100644 --- a/hw/bsp/nrf/boards/pca10095/board.h +++ b/hw/bsp/nrf/boards/pca10095/board.h @@ -46,11 +46,12 @@ #define UART_TX_PIN 20 // SPI for USB host shield -#define MAX3421_SCK_PIN _PINNUM(1, 15) -#define MAX3421_MOSI_PIN _PINNUM(1, 13) -#define MAX3421_MISO_PIN _PINNUM(1, 14) -#define MAX3421_CS_PIN _PINNUM(1, 12) -#define MAX3421_INTR_PIN _PINNUM(1, 11) +// Pin is correct but not working probably due to signal incompatible (1.8V 3v3) with MAC3421E !? +//#define MAX3421_SCK_PIN _PINNUM(1, 15) +//#define MAX3421_MOSI_PIN _PINNUM(1, 13) +//#define MAX3421_MISO_PIN _PINNUM(1, 14) +//#define MAX3421_CS_PIN _PINNUM(1, 12) +//#define MAX3421_INTR_PIN _PINNUM(1, 11) #ifdef __cplusplus } diff --git a/hw/bsp/nrf/family.c b/hw/bsp/nrf/family.c index 55119ef02..71c651f5f 100644 --- a/hw/bsp/nrf/family.c +++ b/hw/bsp/nrf/family.c @@ -292,20 +292,7 @@ void max3421_int_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { } static void max3421_init(void) { - // MAX3421 need 3.3v signal (may not be needed) -// #if defined(UICR_REGOUT0_VOUT_Msk) -// if ((NRF_UICR->REGOUT0 & UICR_REGOUT0_VOUT_Msk) != UICR_REGOUT0_VOUT_3V3) { -// NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos; -// while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} -// -// NRF_UICR->REGOUT0 = (NRF_UICR->REGOUT0 & ~UICR_REGOUT0_VOUT_Msk) | UICR_REGOUT0_VOUT_3V3; -// -// NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos; -// while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} -// -// NVIC_SystemReset(); -// } -// #endif + // Somehow pca10056/95 is not working probably due to signal incompatible (1.8V 3v3) with MAC3421E !? // manually manage CS nrf_gpio_cfg_output(MAX3421_CS_PIN); From 74bd2647589790b3bee49146774133c2061a34fe Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 22 Mar 2024 11:42:33 +0700 Subject: [PATCH 150/454] adding deinit() stub for usbh/hcd class driver add TUSB_VERSION_BUILD, also add TUSB_VERSION_NUMBER --- src/class/cdc/cdc_host.c | 4 +++ src/class/cdc/cdc_host.h | 1 + src/class/hid/hid_host.c | 4 +++ src/class/hid/hid_host.h | 1 + src/class/msc/msc_host.c | 5 ++++ src/class/msc/msc_host.h | 1 + src/host/hcd.h | 3 +++ src/host/hub.c | 7 +++-- src/host/hub.h | 1 + src/host/usbh.c | 55 ++++++++++++++++++++++++++++++---------- src/host/usbh.h | 4 +++ src/host/usbh_pvt.h | 4 +-- src/tusb_option.h | 5 ++++ 13 files changed, 76 insertions(+), 19 deletions(-) diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 2fb37d835..14f380b40 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -637,6 +637,10 @@ void cdch_init(void) { } } +bool cdch_deinit(void) { + return true; +} + void cdch_close(uint8_t daddr) { for (uint8_t idx = 0; idx < CFG_TUH_CDC; idx++) { cdch_interface_t* p_cdc = &cdch_data[idx]; diff --git a/src/class/cdc/cdc_host.h b/src/class/cdc/cdc_host.h index d512a23a5..7530b1e9d 100644 --- a/src/class/cdc/cdc_host.h +++ b/src/class/cdc/cdc_host.h @@ -193,6 +193,7 @@ TU_ATTR_WEAK extern void tuh_cdc_tx_complete_cb(uint8_t idx); // Internal Class Driver API //--------------------------------------------------------------------+ void cdch_init (void); +bool cdch_deinit (void); bool cdch_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len); bool cdch_set_config (uint8_t dev_addr, uint8_t itf_num); bool cdch_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 7330fa237..16e2d3c2c 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -376,6 +376,10 @@ void hidh_init(void) { tu_memclr(_hidh_itf, sizeof(_hidh_itf)); } +bool hidh_deinit(void) { + return true; +} + bool hidh_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void) result; diff --git a/src/class/hid/hid_host.h b/src/class/hid/hid_host.h index 17f4e27c0..9ea222b3d 100644 --- a/src/class/hid/hid_host.h +++ b/src/class/hid/hid_host.h @@ -164,6 +164,7 @@ TU_ATTR_WEAK void tuh_hid_set_protocol_complete_cb(uint8_t dev_addr, uint8_t idx // Internal Class Driver API //--------------------------------------------------------------------+ void hidh_init(void); +bool hidh_deinit(void); bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const* desc_itf, uint16_t max_len); bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num); bool hidh_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index 39f2d9f1c..61ecb8e4e 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -288,6 +288,11 @@ void msch_init(void) { tu_memclr(_msch_itf, sizeof(_msch_itf)); } +bool msch_deinit(void) { + return true; +} + + void msch_close(uint8_t dev_addr) { TU_VERIFY(dev_addr <= CFG_TUH_DEVICE_MAX,); msch_interface_t* p_msc = get_itf(dev_addr); diff --git a/src/class/msc/msc_host.h b/src/class/msc/msc_host.h index 9ca1b4703..5bf2e62e3 100644 --- a/src/class/msc/msc_host.h +++ b/src/class/msc/msc_host.h @@ -114,6 +114,7 @@ TU_ATTR_WEAK void tuh_msc_umount_cb(uint8_t dev_addr); //--------------------------------------------------------------------+ void msch_init (void); +bool msch_deinit (void); bool msch_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len); bool msch_set_config (uint8_t dev_addr, uint8_t itf_num); void msch_close (uint8_t dev_addr); diff --git a/src/host/hcd.h b/src/host/hcd.h index 2bde289df..d5804c608 100644 --- a/src/host/hcd.h +++ b/src/host/hcd.h @@ -130,6 +130,9 @@ bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) TU_AT // Initialize controller to host mode bool hcd_init(uint8_t rhport); +// De-initialize controller +bool hcd_deinit(uint8_t rhport); + // Interrupt Handler void hcd_int_handler(uint8_t rhport, bool in_isr); diff --git a/src/host/hub.c b/src/host/hub.c index 3bac18698..0853ff27a 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -182,11 +182,14 @@ bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp, //--------------------------------------------------------------------+ // CLASS-USBH API (don't require to verify parameters) //--------------------------------------------------------------------+ -void hub_init(void) -{ +void hub_init(void) { tu_memclr(hub_data, sizeof(hub_data)); } +bool hub_deinit(void) { + return true; +} + bool hub_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len) { (void) rhport; diff --git a/src/host/hub.h b/src/host/hub.h index 390740e1f..c3f4a3612 100644 --- a/src/host/hub.h +++ b/src/host/hub.h @@ -205,6 +205,7 @@ static inline bool hub_port_clear_reset_change(uint8_t hub_addr, uint8_t hub_por // Internal Class Driver API //--------------------------------------------------------------------+ void hub_init (void); +bool hub_deinit (void); bool hub_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len); bool hub_set_config (uint8_t dev_addr, uint8_t itf_num); bool hub_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); diff --git a/src/host/usbh.c b/src/host/usbh.c index 625857683..cf348bbb2 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -45,8 +45,13 @@ #endif //--------------------------------------------------------------------+ -// Callback weak stubs (called if application does not provide) +// Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ +TU_ATTR_WEAK bool hcd_deinit(uint8_t rhport) { + (void) rhport; + return false; +} + TU_ATTR_WEAK void tuh_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr) { (void) rhport; (void) eventid; @@ -119,16 +124,17 @@ typedef struct { // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ #if CFG_TUSB_DEBUG >= CFG_TUH_LOG_LEVEL - #define DRIVER_NAME(_name) .name = _name, + #define DRIVER_NAME(_name) _name #else - #define DRIVER_NAME(_name) + #define DRIVER_NAME(_name) NULL #endif static usbh_class_driver_t const usbh_class_drivers[] = { #if CFG_TUH_CDC { - DRIVER_NAME("CDC") + .name = DRIVER_NAME("CDC"), .init = cdch_init, + .deinit = cdch_deinit, .open = cdch_open, .set_config = cdch_set_config, .xfer_cb = cdch_xfer_cb, @@ -138,8 +144,9 @@ static usbh_class_driver_t const usbh_class_drivers[] = { #if CFG_TUH_MSC { - DRIVER_NAME("MSC") + .name = DRIVER_NAME("MSC"), .init = msch_init, + .deinit = msch_deinit, .open = msch_open, .set_config = msch_set_config, .xfer_cb = msch_xfer_cb, @@ -149,8 +156,9 @@ static usbh_class_driver_t const usbh_class_drivers[] = { #if CFG_TUH_HID { - DRIVER_NAME("HID") + .name = DRIVER_NAME("HID"), .init = hidh_init, + .deinit = hidh_deinit, .open = hidh_open, .set_config = hidh_set_config, .xfer_cb = hidh_xfer_cb, @@ -160,8 +168,9 @@ static usbh_class_driver_t const usbh_class_drivers[] = { #if CFG_TUH_HUB { - DRIVER_NAME("HUB") + .name = DRIVER_NAME("HUB"), .init = hub_init, + .deinit = hub_deinit, .open = hub_open, .set_config = hub_set_config, .xfer_cb = hub_xfer_cb, @@ -171,9 +180,11 @@ static usbh_class_driver_t const usbh_class_drivers[] = { #if CFG_TUH_VENDOR { - DRIVER_NAME("VENDOR") + .name = DRIVER_NAME("VENDOR"), .init = cush_init, - .open = cush_open_subtask, + .deinit = cush_deinit, + .open = cush_open, + .set_config = cush_set_config, .xfer_cb = cush_isr, .close = cush_close } @@ -338,11 +349,11 @@ bool tuh_inited(void) { return _usbh_controller != TUSB_INDEX_INVALID_8; } -bool tuh_init(uint8_t controller_id) { +bool tuh_init(uint8_t rhport) { // skip if already initialized if ( tuh_inited() ) return true; - TU_LOG_USBH("USBH init on controller %u\r\n", controller_id); + TU_LOG_USBH("USBH init on controller %u\r\n", rhport); TU_LOG_INT_USBH(sizeof(usbh_device_t)); TU_LOG_INT_USBH(sizeof(hcd_event_t)); TU_LOG_INT_USBH(sizeof(_ctrl_xfer)); @@ -383,10 +394,26 @@ bool tuh_init(uint8_t controller_id) { } } - _usbh_controller = controller_id;; + _usbh_controller = rhport;; - TU_ASSERT(hcd_init(controller_id)); - hcd_int_enable(controller_id); + TU_ASSERT(hcd_init(rhport)); + hcd_int_enable(rhport); + + return true; +} + +bool tuh_deinit(uint8_t rhport) { + if (!tuh_rhport_is_active(rhport)) return true; + + hcd_int_disable(rhport); + hcd_deinit(rhport); + + _usbh_controller = TUSB_INDEX_INVALID_8; + + // no other controller is active, deinit the stack + if (!tuh_inited()) { + + } return true; } diff --git a/src/host/usbh.h b/src/host/usbh.h index 9ff118543..0e31e80a7 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -109,7 +109,11 @@ bool tuh_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param); // Init host stack bool tuh_init(uint8_t rhport); +// Deinit host stack on rhport +bool tuh_deinit(uint8_t rhport); + // Check if host stack is already initialized with any roothub ports +// To check if an rhport is initialized, use tuh_rhport_is_active() bool tuh_inited(void); // Task function should be called in main/rtos loop, extended version of tuh_task() diff --git a/src/host/usbh_pvt.h b/src/host/usbh_pvt.h index 4ed2a72b5..204315175 100644 --- a/src/host/usbh_pvt.h +++ b/src/host/usbh_pvt.h @@ -50,11 +50,9 @@ enum { //--------------------------------------------------------------------+ typedef struct { - #if CFG_TUSB_DEBUG >= CFG_TUH_LOG_LEVEL char const* name; - #endif - void (* const init )(void); + bool (* const deinit )(void); bool (* const open )(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool (* const set_config )(uint8_t dev_addr, uint8_t itf_num); bool (* const xfer_cb )(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); diff --git a/src/tusb_option.h b/src/tusb_option.h index 96378cb80..22f27e9e1 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -29,9 +29,14 @@ #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. #define TUSB_VERSION_MAJOR 0 #define TUSB_VERSION_MINOR 16 #define TUSB_VERSION_REVISION 0 +#define TUSB_VERSION_BUILD 1 + +#define TUSB_VERSION_NUMBER (TUSB_VERSION_MAJOR << 24 | TUSB_VERSION_MINOR << 16 | TUSB_VERSION_REVISION << 8 | TUSB_VERSION_BUILD) #define TUSB_VERSION_STRING TU_STRING(TUSB_VERSION_MAJOR) "." TU_STRING(TUSB_VERSION_MINOR) "." TU_STRING(TUSB_VERSION_REVISION) //--------------------------------------------------------------------+ From 2cf171095e02d8562ff138520cbe686e013f4522 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 22 Mar 2024 12:30:14 +0700 Subject: [PATCH 151/454] code format --- src/common/tusb_fifo.h | 31 ++--- src/tusb.c | 277 +++++++++++++++-------------------------- 2 files changed, 113 insertions(+), 195 deletions(-) diff --git a/src/common/tusb_fifo.h b/src/common/tusb_fifo.h index 2f60ec2f4..2d9f5e667 100644 --- a/src/common/tusb_fifo.h +++ b/src/common/tusb_fifo.h @@ -102,10 +102,8 @@ extern "C" { * | * ------------------------- * | R | 1 | 2 | W | 4 | 5 | - */ -typedef struct -{ +typedef struct { uint8_t* buffer ; // buffer pointer uint16_t depth ; // max items @@ -124,16 +122,14 @@ typedef struct } tu_fifo_t; -typedef struct -{ +typedef struct { uint16_t len_lin ; ///< linear length in item size uint16_t len_wrap ; ///< wrapped length in item size void * ptr_lin ; ///< linear part start pointer void * ptr_wrap ; ///< wrapped part start pointer } tu_fifo_buffer_info_t; -#define TU_FIFO_INIT(_buffer, _depth, _type, _overwritable) \ -{ \ +#define TU_FIFO_INIT(_buffer, _depth, _type, _overwritable){\ .buffer = _buffer, \ .depth = _depth, \ .item_size = sizeof(_type), \ @@ -144,23 +140,18 @@ typedef struct uint8_t _name##_buf[_depth*sizeof(_type)]; \ tu_fifo_t _name = TU_FIFO_INIT(_name##_buf, _depth, _type, _overwritable) - bool tu_fifo_set_overwritable(tu_fifo_t *f, bool overwritable); 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); @@ -182,8 +173,7 @@ bool tu_fifo_overflowed (tu_fifo_t* f); void tu_fifo_correct_read_pointer (tu_fifo_t* f); TU_ATTR_ALWAYS_INLINE static inline -uint16_t tu_fifo_depth(tu_fifo_t* f) -{ +uint16_t tu_fifo_depth(tu_fifo_t* f) { return f->depth; } @@ -198,7 +188,6 @@ void tu_fifo_advance_read_pointer (tu_fifo_t *f, uint16_t n); void tu_fifo_get_read_info (tu_fifo_t *f, tu_fifo_buffer_info_t *info); void tu_fifo_get_write_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info); - #ifdef __cplusplus } #endif diff --git a/src/tusb.c b/src/tusb.c index 7c86f1ca5..2256dc3b9 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -43,32 +43,30 @@ // Public API //--------------------------------------------------------------------+ -bool tusb_init(void) -{ -#if CFG_TUD_ENABLED && defined(TUD_OPT_RHPORT) +bool tusb_init(void) { + #if CFG_TUD_ENABLED && defined(TUD_OPT_RHPORT) // init device stack CFG_TUSB_RHPORTx_MODE must be defined TU_ASSERT ( tud_init(TUD_OPT_RHPORT) ); -#endif + #endif -#if CFG_TUH_ENABLED && defined(TUH_OPT_RHPORT) + #if CFG_TUH_ENABLED && defined(TUH_OPT_RHPORT) // init host stack CFG_TUSB_RHPORTx_MODE must be defined TU_ASSERT( tuh_init(TUH_OPT_RHPORT) ); -#endif + #endif return true; } -bool tusb_inited(void) -{ +bool tusb_inited(void) { bool ret = false; -#if CFG_TUD_ENABLED + #if CFG_TUD_ENABLED ret = ret || tud_inited(); -#endif + #endif -#if CFG_TUH_ENABLED + #if CFG_TUH_ENABLED ret = ret || tuh_inited(); -#endif + #endif return ret; } @@ -77,30 +75,24 @@ bool tusb_inited(void) // Descriptor helper //--------------------------------------------------------------------+ -uint8_t const * tu_desc_find(uint8_t const* desc, uint8_t const* end, uint8_t byte1) -{ - while(desc+1 < end) - { - if ( desc[1] == byte1 ) return desc; +uint8_t const* tu_desc_find(uint8_t const* desc, uint8_t const* end, uint8_t byte1) { + while (desc + 1 < end) { + if (desc[1] == byte1) return desc; desc += desc[DESC_OFFSET_LEN]; } return NULL; } -uint8_t const * tu_desc_find2(uint8_t const* desc, uint8_t const* end, uint8_t byte1, uint8_t byte2) -{ - while(desc+2 < end) - { - if ( desc[1] == byte1 && desc[2] == byte2) return desc; +uint8_t const* tu_desc_find2(uint8_t const* desc, uint8_t const* end, uint8_t byte1, uint8_t byte2) { + while (desc + 2 < end) { + if (desc[1] == byte1 && desc[2] == byte2) return desc; desc += desc[DESC_OFFSET_LEN]; } return NULL; } -uint8_t const * tu_desc_find3(uint8_t const* desc, uint8_t const* end, uint8_t byte1, uint8_t byte2, uint8_t byte3) -{ - while(desc+3 < end) - { +uint8_t const* tu_desc_find3(uint8_t const* desc, uint8_t const* end, uint8_t byte1, uint8_t byte2, uint8_t byte3) { + while (desc + 3 < end) { if (desc[1] == byte1 && desc[2] == byte2 && desc[3] == byte3) return desc; desc += desc[DESC_OFFSET_LEN]; } @@ -146,83 +138,71 @@ bool tu_edpt_release(tu_edpt_state_t* ep_state, osal_mutex_t mutex) { return ret; } -bool tu_edpt_validate(tusb_desc_endpoint_t const * desc_ep, tusb_speed_t speed) -{ +bool tu_edpt_validate(tusb_desc_endpoint_t const* desc_ep, tusb_speed_t speed) { uint16_t const max_packet_size = tu_edpt_packet_size(desc_ep); TU_LOG2(" Open EP %02X with Size = %u\r\n", desc_ep->bEndpointAddress, max_packet_size); - switch (desc_ep->bmAttributes.xfer) - { - case TUSB_XFER_ISOCHRONOUS: - { + switch (desc_ep->bmAttributes.xfer) { + case TUSB_XFER_ISOCHRONOUS: { uint16_t const spec_size = (speed == TUSB_SPEED_HIGH ? 1024 : 1023); TU_ASSERT(max_packet_size <= spec_size); + break; } - break; case TUSB_XFER_BULK: - if (speed == TUSB_SPEED_HIGH) - { + if (speed == TUSB_SPEED_HIGH) { // Bulk highspeed must be EXACTLY 512 TU_ASSERT(max_packet_size == 512); - }else - { + } else { // TODO Bulk fullspeed can only be 8, 16, 32, 64 TU_ASSERT(max_packet_size <= 64); } - break; + break; - case TUSB_XFER_INTERRUPT: - { + case TUSB_XFER_INTERRUPT: { uint16_t const spec_size = (speed == TUSB_SPEED_HIGH ? 1024 : 64); TU_ASSERT(max_packet_size <= spec_size); + break; } - break; - default: return false; + default: + return false; } return true; } -void tu_edpt_bind_driver(uint8_t ep2drv[][2], tusb_desc_interface_t const* desc_itf, uint16_t desc_len, uint8_t driver_id) -{ +void tu_edpt_bind_driver(uint8_t ep2drv[][2], tusb_desc_interface_t const* desc_itf, uint16_t desc_len, + uint8_t driver_id) { uint8_t const* p_desc = (uint8_t const*) desc_itf; uint8_t const* desc_end = p_desc + desc_len; - while( p_desc < desc_end ) - { - if ( TUSB_DESC_ENDPOINT == tu_desc_type(p_desc) ) - { + while (p_desc < desc_end) { + if (TUSB_DESC_ENDPOINT == tu_desc_type(p_desc)) { uint8_t const ep_addr = ((tusb_desc_endpoint_t const*) p_desc)->bEndpointAddress; - TU_LOG(2, " Bind EP %02x to driver id %u\r\n", ep_addr, driver_id); ep2drv[tu_edpt_number(ep_addr)][tu_edpt_dir(ep_addr)] = driver_id; } - p_desc = tu_desc_next(p_desc); } } -uint16_t tu_desc_get_interface_total_len(tusb_desc_interface_t const* desc_itf, uint8_t itf_count, uint16_t max_len) -{ +uint16_t tu_desc_get_interface_total_len(tusb_desc_interface_t const* desc_itf, uint8_t itf_count, uint16_t max_len) { uint8_t const* p_desc = (uint8_t const*) desc_itf; uint16_t len = 0; - while (itf_count--) - { + while (itf_count--) { // Next on interface desc len += tu_desc_len(desc_itf); p_desc = tu_desc_next(p_desc); - while (len < max_len) - { + while (len < max_len) { // return on IAD regardless of itf count - if ( tu_desc_type(p_desc) == TUSB_DESC_INTERFACE_ASSOCIATION ) return len; - - if ( (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE) && - ((tusb_desc_interface_t const*) p_desc)->bAlternateSetting == 0 ) - { + if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE_ASSOCIATION) { + return len; + } + if ((tu_desc_type(p_desc) == TUSB_DESC_INTERFACE) && + ((tusb_desc_interface_t const*) p_desc)->bAlternateSetting == 0) { break; } @@ -239,8 +219,7 @@ 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) -{ + 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_mutex); (void) new_mutex; (void) is_tx; @@ -256,91 +235,72 @@ bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool ove } TU_ATTR_ALWAYS_INLINE static inline -bool stream_claim(tu_edpt_stream_t* s) -{ - if (s->is_host) - { +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); #endif - }else - { + } else { #if CFG_TUD_ENABLED return usbd_edpt_claim(s->rhport, s->ep_addr); #endif } - return false; } TU_ATTR_ALWAYS_INLINE static inline -bool stream_xfer(tu_edpt_stream_t* s, uint16_t count) -{ - if (s->is_host) - { +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); #endif - }else - { + } else { #if CFG_TUD_ENABLED return usbd_edpt_xfer(s->rhport, 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) -{ - if (s->is_host) - { +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); #endif - }else - { + } else { #if CFG_TUD_ENABLED return usbd_edpt_release(s->rhport, s->ep_addr); #endif } - return false; } //--------------------------------------------------------------------+ // 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(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(!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)); return true; } -uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t* s) -{ +uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t* s) { // skip if no data - TU_VERIFY( tu_fifo_count(&s->ff), 0 ); + TU_VERIFY(tu_fifo_count(&s->ff), 0); // Claim the endpoint - TU_VERIFY( stream_claim(s), 0 ); + TU_VERIFY(stream_claim(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 ); + if (count) { + TU_ASSERT(stream_xfer(s, count), 0); return count; - }else - { + } else { // Release endpoint since we don't make any transfer // Note: data is dropped if terminal is not connected stream_release(s); @@ -348,16 +308,13 @@ 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) -{ +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); // 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) ) - { + if ((tu_fifo_count(&s->ff) >= s->ep_packetsize) || (tu_fifo_depth(&s->ff) < s->ep_packetsize)) { tu_edpt_stream_write_xfer(s); } @@ -367,9 +324,7 @@ uint32_t tu_edpt_stream_write(tu_edpt_stream_t* s, void const *buffer, uint32_t //--------------------------------------------------------------------+ // Stream Read //--------------------------------------------------------------------+ - -uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t* s) -{ +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. @@ -384,25 +339,21 @@ uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t* s) // 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 >= s->ep_packetsize) { // multiple of packet size limit by ep bufsize - uint16_t count = (uint16_t) (available & ~(s->ep_packetsize -1)); + 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(s, count), 0); return count; - }else - { + } else { // Release endpoint since we don't make any transfer stream_release(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(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); return num_read; @@ -416,42 +367,35 @@ uint32_t tu_edpt_stream_read(tu_edpt_stream_t* s, void* buffer, uint32_t bufsize #include #if CFG_TUSB_DEBUG >= CFG_TUH_LOG_LEVEL || CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL - -char const* const tu_str_speed[] = { "Full", "Low", "High" }; -char const* const tu_str_std_request[] = -{ - "Get Status" , - "Clear Feature" , - "Reserved" , - "Set Feature" , - "Reserved" , - "Set Address" , - "Get Descriptor" , - "Set Descriptor" , - "Get Configuration" , - "Set Configuration" , - "Get Interface" , - "Set Interface" , - "Synch Frame" +char const* const tu_str_speed[] = {"Full", "Low", "High"}; +char const* const tu_str_std_request[] = { + "Get Status", + "Clear Feature", + "Reserved", + "Set Feature", + "Reserved", + "Set Address", + "Get Descriptor", + "Set Descriptor", + "Get Configuration", + "Set Configuration", + "Get Interface", + "Set Interface", + "Synch Frame" }; char const* const tu_str_xfer_result[] = { "OK", "FAILED", "STALLED", "TIMEOUT" }; - #endif -static void dump_str_line(uint8_t const* buf, uint16_t count) -{ +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 Date: Fri, 22 Mar 2024 12:53:31 +0700 Subject: [PATCH 152/454] add tu_edpt_stream_deinit() --- src/common/tusb_private.h | 19 +++++++++---------- src/tusb.c | 11 ++++++++++- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h index db1ba974d..373a50256 100644 --- a/src/common/tusb_private.h +++ b/src/common/tusb_private.h @@ -60,7 +60,7 @@ typedef struct { tu_fifo_t ff; // mutex: read if ep rx, write if e tx - OSAL_MUTEX_DEF(ff_mutex); + OSAL_MUTEX_DEF(ff_mutexdef); }tu_edpt_stream_t; @@ -87,15 +87,17 @@ bool tu_edpt_release(tu_edpt_state_t* ep_state, osal_mutex_t mutex); // Endpoint Stream //--------------------------------------------------------------------+ -// Init an stream, should only be called once +// Init an endpoint stream 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); +// Deinit an endpoint stream +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, uint8_t hwid, tusb_desc_endpoint_t const *desc_ep) { tu_fifo_clear(&s->ff); s->hwid = hwid; s->ep_addr = desc_ep->bEndpointAddress; @@ -103,16 +105,14 @@ void tu_edpt_stream_open(tu_edpt_stream_t* s, uint8_t hwid, tusb_desc_endpoint_t } TU_ATTR_ALWAYS_INLINE static inline -void tu_edpt_stream_close(tu_edpt_stream_t* s) -{ +void tu_edpt_stream_close(tu_edpt_stream_t* s) { s->hwid = 0; s->ep_addr = 0; } // Clear fifo TU_ATTR_ALWAYS_INLINE static inline -bool tu_edpt_stream_clear(tu_edpt_stream_t* s) -{ +bool tu_edpt_stream_clear(tu_edpt_stream_t* s) { return tu_fifo_clear(&s->ff); } @@ -131,8 +131,7 @@ bool tu_edpt_stream_write_zlp_if_needed(tu_edpt_stream_t* s, uint32_t last_xferr // 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) -{ +uint32_t tu_edpt_stream_write_available(tu_edpt_stream_t* s) { return (uint32_t) tu_fifo_remaining(&s->ff); } diff --git a/src/tusb.c b/src/tusb.c index 2256dc3b9..074dcce96 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -220,7 +220,7 @@ 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_mutex); + osal_mutex_t new_mutex = osal_mutex_create(&s->ff_mutexdef); (void) new_mutex; (void) is_tx; @@ -234,6 +234,15 @@ bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool ove return true; } +bool tu_edpt_stream_deinit(tu_edpt_stream_t* s) { + (void) s; + #if OSAL_MUTEX_REQUIRED + if (s->ff->mutex_wr) osal_mutex_delete(s->ff->mutex_wr); + if (s->ff->mutex_rd) osal_mutex_delete(s->ff->mutex_rd); + #endif + return true; +} + TU_ATTR_ALWAYS_INLINE static inline bool stream_claim(tu_edpt_stream_t* s) { if (s->is_host) { From 31f68495cf66706926c408ad15ea90a646c62198 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 22 Mar 2024 16:10:26 +0700 Subject: [PATCH 153/454] update osal API add osal_semaphore_delete(), osal_mutex_delete(), osal_queue_delete() --- src/osal/osal.h | 3 ++ src/osal/osal_freertos.h | 19 ++++++- src/osal/osal_mynewt.h | 61 ++++++++++++----------- src/osal/osal_none.h | 16 ++++++ src/osal/osal_pico.h | 105 ++++++++++++++++----------------------- src/osal/osal_rtthread.h | 6 +-- src/osal/osal_rtx4.h | 61 ++++++++++++----------- src/tusb.c | 4 +- 8 files changed, 147 insertions(+), 128 deletions(-) diff --git a/src/osal/osal.h b/src/osal/osal.h index f092e8ffb..8f45ea5c1 100644 --- a/src/osal/osal.h +++ b/src/osal/osal.h @@ -74,15 +74,18 @@ typedef void (*osal_task_func_t)( void * ); // Should be implemented as static inline function in osal_port.h header /* osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef); + bool osal_semaphore_delete(osal_semaphore_t semd_hdl); bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr); bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec); void osal_semaphore_reset(osal_semaphore_t sem_hdl); // TODO removed osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef); + bool osal_mutex_delete(osal_mutex_t mutex_hdl) bool osal_mutex_lock (osal_mutex_t sem_hdl, uint32_t msec); bool osal_mutex_unlock(osal_mutex_t mutex_hdl); osal_queue_t osal_queue_create(osal_queue_def_t* qdef); + bool osal_queue_delete(osal_queue_t qhdl); bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec); bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr); bool osal_queue_empty(osal_queue_t qhdl); diff --git a/src/osal/osal_freertos.h b/src/osal/osal_freertos.h index 501e0bddd..f1f05f353 100644 --- a/src/osal/osal_freertos.h +++ b/src/osal/osal_freertos.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_OSAL_FREERTOS_H_ -#define _TUSB_OSAL_FREERTOS_H_ +#ifndef TUSB_OSAL_FREERTOS_H_ +#define TUSB_OSAL_FREERTOS_H_ // FreeRTOS Headers #include TU_INCLUDE_PATH(CFG_TUSB_OS_INC_PATH,FreeRTOS.h) @@ -114,6 +114,11 @@ TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_ #endif } +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_delete(osal_semaphore_t semd_hdl) { + vSemaphoreDelete(semd_hdl); + return true; +} + TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { if ( !in_isr ) { return xSemaphoreGive(sem_hdl) != 0; @@ -153,6 +158,11 @@ TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_de #endif } +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_delete(osal_mutex_t mutex_hdl) { + vSemaphoreDelete(mutex_hdl); + return true; +} + TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) { return osal_semaphore_wait(mutex_hdl, msec); } @@ -181,6 +191,11 @@ TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_de return q; } +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_delete(osal_queue_t qhdl) { + vQueueDelete(qhdl); + return true; +} + TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) { return xQueueReceive(qhdl, data, _osal_ms2tick(msec)); } diff --git a/src/osal/osal_mynewt.h b/src/osal/osal_mynewt.h index b8ea2087c..16def0d2a 100644 --- a/src/osal/osal_mynewt.h +++ b/src/osal/osal_mynewt.h @@ -36,8 +36,7 @@ //--------------------------------------------------------------------+ // TASK API //--------------------------------------------------------------------+ -TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) -{ +TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) { os_time_delay( os_time_ms_to_ticks32(msec) ); } @@ -47,25 +46,26 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) typedef struct os_sem osal_semaphore_def_t; typedef struct os_sem* osal_semaphore_t; -TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) -{ +TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) { return (os_sem_init(semdef, 0) == OS_OK) ? (osal_semaphore_t) semdef : NULL; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_delete(osal_semaphore_t semd_hdl) { + (void) semd_hdl; + return true; // nothing to do +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { (void) in_isr; return os_sem_release(sem_hdl) == OS_OK; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) { uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? OS_TIMEOUT_NEVER : os_time_ms_to_ticks32(msec); return os_sem_pend(sem_hdl, ticks) == OS_OK; } -static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) -{ +static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) { // TODO implement later } @@ -75,19 +75,21 @@ static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) typedef struct os_mutex osal_mutex_def_t; typedef struct os_mutex* osal_mutex_t; -TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) -{ +TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) { return (os_mutex_init(mdef) == OS_OK) ? (osal_mutex_t) mdef : NULL; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_delete(osal_mutex_t mutex_hdl) { + (void) mutex_hdl; + return true; // nothing to do +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) { uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? OS_TIMEOUT_NEVER : os_time_ms_to_ticks32(msec); return os_mutex_pend(mutex_hdl, ticks) == OS_OK; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) { return os_mutex_release(mutex_hdl) == OS_OK; } @@ -101,8 +103,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hd static struct os_event _name##_##evbuf[_depth];\ osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .buf = _name##_##buf, .evbuf = _name##_##evbuf};\ -typedef struct -{ +typedef struct { uint16_t depth; uint16_t item_sz; void* buf; @@ -116,17 +117,20 @@ typedef struct typedef osal_queue_def_t* osal_queue_t; -TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) -{ - if ( OS_OK != os_mempool_init(&qdef->mpool, qdef->depth, qdef->item_sz, qdef->buf, "usbd queue") ) return NULL; - if ( OS_OK != os_mempool_init(&qdef->epool, qdef->depth, sizeof(struct os_event), qdef->evbuf, "usbd evqueue") ) return NULL; +TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) { + if ( OS_OK != os_mempool_init(&qdef->mpool, qdef->depth, qdef->item_sz, qdef->buf, "usb queue") ) return NULL; + if ( OS_OK != os_mempool_init(&qdef->epool, qdef->depth, sizeof(struct os_event), qdef->evbuf, "usb evqueue") ) return NULL; os_eventq_init(&qdef->evq); return (osal_queue_t) qdef; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_delete(osal_queue_t qhdl) { + (void) qhdl; + return true; // nothing to do +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) { (void) msec; // os_eventq_get() does not take timeout, always behave as msec = WAIT_FOREVER struct os_event* ev; @@ -139,8 +143,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, v return true; } -static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr) -{ +static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr) { (void) in_isr; // get a block from mem pool for data @@ -150,8 +153,7 @@ static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in // get a block from event pool to put into queue struct os_event* ev = (struct os_event*) os_memblock_get(&qhdl->epool); - if (!ev) - { + if (!ev) { os_memblock_put(&qhdl->mpool, ptr); return false; } @@ -163,8 +165,7 @@ static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in return true; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) { return STAILQ_EMPTY(&qhdl->evq.evq_list); } diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index a07d39828..c954fcfe8 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -54,6 +54,12 @@ TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_ return semdef; } +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_delete(osal_semaphore_t semd_hdl) { + (void) semd_hdl; + return true; // nothing to do +} + + TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { (void) in_isr; sem_hdl->count++; @@ -90,6 +96,11 @@ TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_de return mdef; } +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_delete(osal_mutex_t mutex_hdl) { + (void) mutex_hdl; + return true; // nothing to do +} + TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec) { return osal_semaphore_wait(mutex_hdl, msec); } @@ -143,6 +154,11 @@ TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_de return (osal_queue_t) qdef; } +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_delete(osal_queue_t qhdl) { + (void) qhdl; + return true; // nothing to do +} + TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) { (void) msec; // not used, always behave as msec = 0 diff --git a/src/osal/osal_pico.h b/src/osal/osal_pico.h index e6efa0968..00c589ef9 100644 --- a/src/osal/osal_pico.h +++ b/src/osal/osal_pico.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_OSAL_PICO_H_ -#define _TUSB_OSAL_PICO_H_ +#ifndef TUSB_OSAL_PICO_H_ +#define TUSB_OSAL_PICO_H_ #include "pico/time.h" #include "pico/sem.h" @@ -33,42 +33,42 @@ #include "pico/critical_section.h" #ifdef __cplusplus - extern "C" { +extern "C" { #endif //--------------------------------------------------------------------+ // TASK API //--------------------------------------------------------------------+ -TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) -{ +TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) { sleep_ms(msec); } //--------------------------------------------------------------------+ // Binary Semaphore API //--------------------------------------------------------------------+ -typedef struct semaphore osal_semaphore_def_t, *osal_semaphore_t; +typedef struct semaphore osal_semaphore_def_t, * osal_semaphore_t; -TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) -{ +TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) { sem_init(semdef, 0, 255); return semdef; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_delete(osal_semaphore_t semd_hdl) { + (void) semd_hdl; + return true; // nothing to do +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { (void) in_isr; sem_release(sem_hdl); return true; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) { return sem_acquire_timeout_ms(sem_hdl, msec); } -TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) -{ +TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) { sem_reset(sem_hdl, 0); } @@ -76,21 +76,23 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t s // MUTEX API // Within tinyusb, mutex is never used in ISR context //--------------------------------------------------------------------+ -typedef struct mutex osal_mutex_def_t, *osal_mutex_t; +typedef struct mutex osal_mutex_def_t, * osal_mutex_t; -TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) -{ +TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) { mutex_init(mdef); return mdef; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_delete(osal_mutex_t mutex_hdl) { + (void) mutex_hdl; + return true; // nothing to do +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) { return mutex_enter_timeout_ms(mutex_hdl, msec); } -TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) { mutex_exit(mutex_hdl); return true; } @@ -100,75 +102,54 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hd //--------------------------------------------------------------------+ #include "common/tusb_fifo.h" -typedef struct -{ - tu_fifo_t ff; - struct critical_section critsec; // osal_queue may be used in IRQs, so need critical section +typedef struct { + tu_fifo_t ff; + struct critical_section critsec; // osal_queue may be used in IRQs, so need critical section } osal_queue_def_t; typedef osal_queue_def_t* osal_queue_t; // role device/host is used by OS NONE for mutex (disable usb isr) only -#define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \ +#define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \ uint8_t _name##_buf[_depth*sizeof(_type)]; \ osal_queue_def_t _name = { \ .ff = TU_FIFO_INIT(_name##_buf, _depth, _type, false) \ } -// lock queue by disable USB interrupt -TU_ATTR_ALWAYS_INLINE static inline void _osal_q_lock(osal_queue_t qhdl) -{ - critical_section_enter_blocking(&qhdl->critsec); -} - -// unlock queue -TU_ATTR_ALWAYS_INLINE static inline void _osal_q_unlock(osal_queue_t qhdl) -{ - critical_section_exit(&qhdl->critsec); -} - -TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) -{ +TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) { critical_section_init(&qdef->critsec); tu_fifo_clear(&qdef->ff); return (osal_queue_t) qdef; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_delete(osal_queue_t qhdl) { + osal_queue_def_t* qdef = (osal_queue_def_t*) qhdl; + critical_section_deinit(&qdef->critsec); + return true; +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) { (void) msec; // not used, always behave as msec = 0 - // TODO: revisit... docs say that mutexes are never used from IRQ context, - // however osal_queue_recieve may be. therefore my assumption is that - // the fifo mutex is not populated for queues used from an IRQ context - //assert(!qhdl->ff.mutex); - - _osal_q_lock(qhdl); + critical_section_enter_blocking(&qhdl->critsec); bool success = tu_fifo_read(&qhdl->ff, data); - _osal_q_unlock(qhdl); + critical_section_exit(&qhdl->critsec); return success; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr) -{ - // TODO: revisit... docs say that mutexes are never used from IRQ context, - // however osal_queue_recieve may be. therefore my assumption is that - // the fifo mutex is not populated for queues used from an IRQ context - //assert(!qhdl->ff.mutex); +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const* data, bool in_isr) { (void) in_isr; - _osal_q_lock(qhdl); + critical_section_enter_blocking(&qhdl->critsec); bool success = tu_fifo_write(&qhdl->ff, data); - _osal_q_unlock(qhdl); + critical_section_exit(&qhdl->critsec); TU_ASSERT(success); - return success; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) { // TODO: revisit; whether this is true or not currently, tu_fifo_empty is a single // volatile read. @@ -178,7 +159,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) } #ifdef __cplusplus - } +} #endif -#endif /* _TUSB_OSAL_PICO_H_ */ +#endif diff --git a/src/osal/osal_rtthread.h b/src/osal/osal_rtthread.h index d03b53bee..a8423086f 100644 --- a/src/osal/osal_rtthread.h +++ b/src/osal/osal_rtthread.h @@ -25,8 +25,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_OSAL_RTTHREAD_H_ -#define _TUSB_OSAL_RTTHREAD_H_ +#ifndef TUSB_OSAL_RTTHREAD_H_ +#define TUSB_OSAL_RTTHREAD_H_ // RT-Thread Headers #include "rtthread.h" @@ -133,4 +133,4 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) { } #endif -#endif /* _TUSB_OSAL_RTTHREAD_H_ */ +#endif diff --git a/src/osal/osal_rtx4.h b/src/osal/osal_rtx4.h index e443135e0..35909e4d6 100644 --- a/src/osal/osal_rtx4.h +++ b/src/osal/osal_rtx4.h @@ -25,8 +25,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_OSAL_RTX4_H_ -#define _TUSB_OSAL_RTX4_H_ +#ifndef TUSB_OSAL_RTX4_H_ +#define TUSB_OSAL_RTX4_H_ #include @@ -37,8 +37,7 @@ extern "C" { //--------------------------------------------------------------------+ // TASK API //--------------------------------------------------------------------+ -TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) -{ +TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) { uint16_t hi = msec >> 16; uint16_t lo = msec; while (hi--) { @@ -48,12 +47,13 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) } TU_ATTR_ALWAYS_INLINE static inline uint16_t msec2wait(uint32_t msec) { - if (msec == OSAL_TIMEOUT_WAIT_FOREVER) + if (msec == OSAL_TIMEOUT_WAIT_FOREVER) { return 0xFFFF; - else if (msec >= 0xFFFE) + } else if (msec >= 0xFFFE) { return 0xFFFE; - else + } else { return msec; + } } //--------------------------------------------------------------------+ @@ -67,6 +67,11 @@ TU_ATTR_ALWAYS_INLINE static inline OS_ID osal_semaphore_create(osal_semaphore_d return semdef; } +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_delete(osal_semaphore_t semd_hdl) { + (void) semd_hdl; + return true; // nothing to do +} + TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { if ( !in_isr ) { os_sem_send(sem_hdl); @@ -90,19 +95,21 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t c typedef OS_MUT osal_mutex_def_t; typedef OS_ID osal_mutex_t; -TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) -{ +TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) { os_mut_init(mdef); return mdef; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_delete(osal_mutex_t mutex_hdl) { + (void) mutex_hdl; + return true; // nothing to do +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec) { return os_mut_wait(mutex_hdl, msec2wait(msec)) != OS_R_TMO; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) { return os_mut_release(mutex_hdl) == OS_R_OK; } @@ -116,9 +123,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hd _declare_box(_name##__pool, sizeof(_type), _depth); \ osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .pool = _name##__pool, .mbox = _name##__mbox }; - -typedef struct -{ +typedef struct { uint16_t depth; uint16_t item_sz; U32* pool; @@ -127,15 +132,13 @@ typedef struct typedef osal_queue_def_t* osal_queue_t; -TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) -{ +TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) { os_mbx_init(qdef->mbox, (qdef->depth + 4) * 4); _init_box(qdef->pool, ((qdef->item_sz+3)/4)*(qdef->depth) + 3, qdef->item_sz); return qdef; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) { void* buf; os_mbx_wait(qhdl->mbox, &buf, msec2wait(msec)); memcpy(data, buf, qhdl->item_sz); @@ -143,23 +146,23 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, v return true; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_delete(osal_queue_t qhdl) { + (void) qhdl; + return true; // nothing to do ? +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr) { void* buf = _alloc_box(qhdl->pool); memcpy(buf, data, qhdl->item_sz); - if ( !in_isr ) - { + if ( !in_isr ) { os_mbx_send(qhdl->mbox, buf, 0xFFFF); - } - else - { + } else { isr_mbx_send(qhdl->mbox, buf); } return true; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) { return os_mbx_check(qhdl->mbox) == qhdl->depth; } diff --git a/src/tusb.c b/src/tusb.c index 074dcce96..0f09acb64 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -237,8 +237,8 @@ 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) { (void) s; #if OSAL_MUTEX_REQUIRED - if (s->ff->mutex_wr) osal_mutex_delete(s->ff->mutex_wr); - if (s->ff->mutex_rd) osal_mutex_delete(s->ff->mutex_rd); + if (s->ff.mutex_wr) osal_mutex_delete(s->ff.mutex_wr); + if (s->ff.mutex_rd) osal_mutex_delete(s->ff.mutex_rd); #endif return true; } From e84c9f3e221092687808f175e1e19732a10fea72 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 22 Mar 2024 16:12:57 +0700 Subject: [PATCH 154/454] implement tuh_init() change usbh driver init() return type from void to bool --- src/class/cdc/cdc_host.c | 12 ++++-- src/class/cdc/cdc_host.h | 2 +- src/class/hid/hid_host.c | 4 +- src/class/hid/hid_host.h | 2 +- src/class/msc/msc_host.c | 5 ++- src/class/msc/msc_host.h | 2 +- src/host/hub.c | 3 +- src/host/hub.h | 12 +++--- src/host/usbh.c | 85 +++++++++++++++++++++++++--------------- src/host/usbh_pvt.h | 2 +- 10 files changed, 79 insertions(+), 50 deletions(-) diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 14f380b40..5bdd41f1f 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -621,12 +621,11 @@ bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding, // CLASS-USBH API //--------------------------------------------------------------------+ -void cdch_init(void) { +bool cdch_init(void) { + TU_LOG_DRV("sizeof(cdch_interface_t) = %u\r\n", sizeof(cdch_interface_t)); tu_memclr(cdch_data, sizeof(cdch_data)); - for (size_t i = 0; i < CFG_TUH_CDC; i++) { cdch_interface_t* p_cdc = &cdch_data[i]; - tu_edpt_stream_init(&p_cdc->stream.tx, true, true, false, p_cdc->stream.tx_ff_buf, CFG_TUH_CDC_TX_BUFSIZE, p_cdc->stream.tx_ep_buf, CFG_TUH_CDC_TX_EPSIZE); @@ -635,9 +634,16 @@ void cdch_init(void) { p_cdc->stream.rx_ff_buf, CFG_TUH_CDC_RX_BUFSIZE, p_cdc->stream.rx_ep_buf, CFG_TUH_CDC_RX_EPSIZE); } + + return true; } bool cdch_deinit(void) { + for (size_t i = 0; i < CFG_TUH_CDC; i++) { + cdch_interface_t* p_cdc = &cdch_data[i]; + tu_edpt_stream_deinit(&p_cdc->stream.tx); + tu_edpt_stream_deinit(&p_cdc->stream.rx); + } return true; } diff --git a/src/class/cdc/cdc_host.h b/src/class/cdc/cdc_host.h index 7530b1e9d..b63dd1530 100644 --- a/src/class/cdc/cdc_host.h +++ b/src/class/cdc/cdc_host.h @@ -192,7 +192,7 @@ TU_ATTR_WEAK extern void tuh_cdc_tx_complete_cb(uint8_t idx); //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ -void cdch_init (void); +bool cdch_init (void); bool cdch_deinit (void); bool cdch_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len); bool cdch_set_config (uint8_t dev_addr, uint8_t itf_num); diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 16e2d3c2c..efc54656e 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -372,8 +372,10 @@ bool tuh_hid_send_report(uint8_t daddr, uint8_t idx, uint8_t report_id, const vo //--------------------------------------------------------------------+ // USBH API //--------------------------------------------------------------------+ -void hidh_init(void) { +bool hidh_init(void) { + TU_LOG_DRV("sizeof(hidh_interface_t) = %u\r\n", sizeof(hidh_interface_t)); tu_memclr(_hidh_itf, sizeof(_hidh_itf)); + return true; } bool hidh_deinit(void) { diff --git a/src/class/hid/hid_host.h b/src/class/hid/hid_host.h index 9ea222b3d..0902bf1af 100644 --- a/src/class/hid/hid_host.h +++ b/src/class/hid/hid_host.h @@ -163,7 +163,7 @@ TU_ATTR_WEAK void tuh_hid_set_protocol_complete_cb(uint8_t dev_addr, uint8_t idx //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ -void hidh_init(void); +bool hidh_init(void); bool hidh_deinit(void); bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const* desc_itf, uint16_t max_len); bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num); diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index 61ecb8e4e..ce6e7fb2d 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -284,15 +284,16 @@ bool tuh_msc_reset(uint8_t dev_addr) { //--------------------------------------------------------------------+ // CLASS-USBH API //--------------------------------------------------------------------+ -void msch_init(void) { +bool msch_init(void) { + TU_LOG_DRV("sizeof(msch_interface_t) = %u\r\n", sizeof(msch_interface_t)); tu_memclr(_msch_itf, sizeof(_msch_itf)); + return true; } bool msch_deinit(void) { return true; } - void msch_close(uint8_t dev_addr) { TU_VERIFY(dev_addr <= CFG_TUH_DEVICE_MAX,); msch_interface_t* p_msc = get_itf(dev_addr); diff --git a/src/class/msc/msc_host.h b/src/class/msc/msc_host.h index 5bf2e62e3..9fda566d8 100644 --- a/src/class/msc/msc_host.h +++ b/src/class/msc/msc_host.h @@ -113,7 +113,7 @@ TU_ATTR_WEAK void tuh_msc_umount_cb(uint8_t dev_addr); // Internal Class Driver API //--------------------------------------------------------------------+ -void msch_init (void); +bool msch_init (void); bool msch_deinit (void); bool msch_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len); bool msch_set_config (uint8_t dev_addr, uint8_t itf_num); diff --git a/src/host/hub.c b/src/host/hub.c index 0853ff27a..e97014443 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -182,8 +182,9 @@ bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp, //--------------------------------------------------------------------+ // CLASS-USBH API (don't require to verify parameters) //--------------------------------------------------------------------+ -void hub_init(void) { +bool hub_init(void) { tu_memclr(hub_data, sizeof(hub_data)); + return true; } bool hub_deinit(void) { diff --git a/src/host/hub.h b/src/host/hub.h index c3f4a3612..385efe6b2 100644 --- a/src/host/hub.h +++ b/src/host/hub.h @@ -187,16 +187,14 @@ bool hub_port_get_status (uint8_t hub_addr, uint8_t hub_port, void* resp, bool hub_edpt_status_xfer(uint8_t dev_addr); // Reset a port -static inline bool hub_port_reset(uint8_t hub_addr, uint8_t hub_port, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ +TU_ATTR_ALWAYS_INLINE static inline +bool hub_port_reset(uint8_t hub_addr, uint8_t hub_port, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return hub_port_set_feature(hub_addr, hub_port, HUB_FEATURE_PORT_RESET, complete_cb, user_data); } // Clear Reset Change -static inline bool hub_port_clear_reset_change(uint8_t hub_addr, uint8_t hub_port, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ +TU_ATTR_ALWAYS_INLINE static inline +bool hub_port_clear_reset_change(uint8_t hub_addr, uint8_t hub_port, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return hub_port_clear_feature(hub_addr, hub_port, HUB_FEATURE_PORT_RESET_CHANGE, complete_cb, user_data); } @@ -204,7 +202,7 @@ static inline bool hub_port_clear_reset_change(uint8_t hub_addr, uint8_t hub_por //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ -void hub_init (void); +bool hub_init (void); bool hub_deinit (void); bool hub_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len); bool hub_set_config (uint8_t dev_addr, uint8_t itf_num); diff --git a/src/host/usbh.c b/src/host/usbh.c index cf348bbb2..1edc43fd6 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -351,51 +351,55 @@ bool tuh_inited(void) { bool tuh_init(uint8_t rhport) { // skip if already initialized - if ( tuh_inited() ) return true; + if (tuh_rhport_is_active(rhport)) return true; TU_LOG_USBH("USBH init on controller %u\r\n", rhport); - TU_LOG_INT_USBH(sizeof(usbh_device_t)); - TU_LOG_INT_USBH(sizeof(hcd_event_t)); - TU_LOG_INT_USBH(sizeof(_ctrl_xfer)); - TU_LOG_INT_USBH(sizeof(tuh_xfer_t)); - TU_LOG_INT_USBH(sizeof(tu_fifo_t)); - TU_LOG_INT_USBH(sizeof(tu_edpt_stream_t)); - // Event queue - _usbh_q = osal_queue_create( &_usbh_qdef ); - TU_ASSERT(_usbh_q != NULL); + // Init host stack if not already + if (!tuh_inited()) { + TU_LOG_INT_USBH(sizeof(usbh_device_t)); + TU_LOG_INT_USBH(sizeof(hcd_event_t)); + TU_LOG_INT_USBH(sizeof(_ctrl_xfer)); + TU_LOG_INT_USBH(sizeof(tuh_xfer_t)); + TU_LOG_INT_USBH(sizeof(tu_fifo_t)); + TU_LOG_INT_USBH(sizeof(tu_edpt_stream_t)); + + // Event queue + _usbh_q = osal_queue_create(&_usbh_qdef); + TU_ASSERT(_usbh_q != NULL); #if OSAL_MUTEX_REQUIRED - // Init mutex - _usbh_mutex = osal_mutex_create(&_usbh_mutexdef); - TU_ASSERT(_usbh_mutex); + // Init mutex + _usbh_mutex = osal_mutex_create(&_usbh_mutexdef); + TU_ASSERT(_usbh_mutex); #endif - // Get application driver if available - if ( usbh_app_driver_get_cb ) { - _app_driver = usbh_app_driver_get_cb(&_app_driver_count); - } + // Get application driver if available + if (usbh_app_driver_get_cb) { + _app_driver = usbh_app_driver_get_cb(&_app_driver_count); + } - // Device - tu_memclr(&_dev0, sizeof(_dev0)); - tu_memclr(_usbh_devices, sizeof(_usbh_devices)); - tu_memclr(&_ctrl_xfer, sizeof(_ctrl_xfer)); + // Device + tu_memclr(&_dev0, sizeof(_dev0)); + tu_memclr(_usbh_devices, sizeof(_usbh_devices)); + tu_memclr(&_ctrl_xfer, sizeof(_ctrl_xfer)); - for(uint8_t i=0; iname); - driver->init(); + // Class drivers + for (uint8_t drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) { + usbh_class_driver_t const* driver = get_driver(drv_id); + if (driver) { + TU_LOG_USBH("%s init\r\n", driver->name); + driver->init(); + } } } + // Init host controller _usbh_controller = rhport;; - TU_ASSERT(hcd_init(rhport)); hcd_int_enable(rhport); @@ -405,14 +409,31 @@ bool tuh_init(uint8_t rhport) { bool tuh_deinit(uint8_t rhport) { if (!tuh_rhport_is_active(rhport)) return true; + // deinit host controller hcd_int_disable(rhport); hcd_deinit(rhport); _usbh_controller = TUSB_INDEX_INVALID_8; - // no other controller is active, deinit the stack + // deinit host stack if no controller is active if (!tuh_inited()) { + // Class drivers + for (uint8_t drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) { + usbh_class_driver_t const* driver = get_driver(drv_id); + if (driver) { + TU_LOG_USBH("%s deinit\r\n", driver->name); + driver->deinit(); + } + } + osal_queue_delete(_usbh_q); + _usbh_q = NULL; + + #if OSAL_MUTEX_REQUIRED + // TODO make sure there is no task waiting on this mutex + osal_mutex_delete(_usbh_mutex); + _usbh_mutex = NULL; + #endif } return true; diff --git a/src/host/usbh_pvt.h b/src/host/usbh_pvt.h index 204315175..95de915e9 100644 --- a/src/host/usbh_pvt.h +++ b/src/host/usbh_pvt.h @@ -51,7 +51,7 @@ enum { typedef struct { char const* name; - void (* const init )(void); + bool (* const init )(void); bool (* const deinit )(void); bool (* const open )(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool (* const set_config )(uint8_t dev_addr, uint8_t itf_num); From baffadca914bada1663fbb444246ecad681365fb Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 22 Mar 2024 17:54:08 +0700 Subject: [PATCH 155/454] remove pca10095 suppport for max3421 also remove pico_bootsel_via_double_reset from rp2040 --- examples/host/CMakeLists.txt | 1 + hw/bsp/nrf/boards/pca10095/board.cmake | 3 --- hw/bsp/rp2040/family.cmake | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/examples/host/CMakeLists.txt b/examples/host/CMakeLists.txt index bedd2220b..e6a2ece14 100644 --- a/examples/host/CMakeLists.txt +++ b/examples/host/CMakeLists.txt @@ -8,5 +8,6 @@ family_initialize_project(tinyusb_host_examples ${CMAKE_CURRENT_LIST_DIR}) # family_add_subdirectory will filter what to actually add based on selected FAMILY family_add_subdirectory(bare_api) family_add_subdirectory(cdc_msc_hid) +family_add_subdirectory(cdc_msc_hid_freertos) family_add_subdirectory(hid_controller) family_add_subdirectory(msc_file_explorer) diff --git a/hw/bsp/nrf/boards/pca10095/board.cmake b/hw/bsp/nrf/boards/pca10095/board.cmake index 0fbc1d31f..ca5399a3a 100644 --- a/hw/bsp/nrf/boards/pca10095/board.cmake +++ b/hw/bsp/nrf/boards/pca10095/board.cmake @@ -1,9 +1,6 @@ set(MCU_VARIANT nrf5340_application) set(LD_FILE_GNU ${NRFX_DIR}/mdk/nrf5340_xxaa_application.ld) -# enable max3421 host driver for this board -set(MAX3421_HOST 1) - function(update_board TARGET) target_sources(${TARGET} PRIVATE ${NRFX_DIR}/drivers/src/nrfx_usbreg.c diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake index ec40806fd..861d20bdd 100644 --- a/hw/bsp/rp2040/family.cmake +++ b/hw/bsp/rp2040/family.cmake @@ -171,7 +171,7 @@ function(family_configure_target TARGET RTOS) pico_add_extra_outputs(${TARGET}) pico_enable_stdio_uart(${TARGET} 1) - target_link_libraries(${TARGET} PUBLIC pico_stdlib pico_bootsel_via_double_reset tinyusb_board${RTOS_SUFFIX} tinyusb_additions) + target_link_libraries(${TARGET} PUBLIC pico_stdlib tinyusb_board${RTOS_SUFFIX} tinyusb_additions) family_flash_openocd(${TARGET} ${OPENOCD_OPTION}) family_flash_jlink(${TARGET}) From 54e35dd3cf0db737afcb3af2237a3bed85cab1e6 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 22 Mar 2024 18:52:52 +0700 Subject: [PATCH 156/454] bump up upload artifact to v4 --- .github/workflows/build_esp.yml | 2 +- .github/workflows/cifuzz.yml | 2 +- .github/workflows/cmake_arm.yml | 6 +++--- .github/workflows/codeql.yml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build_esp.yml b/.github/workflows/build_esp.yml index 8fbdb31ff..6106592de 100644 --- a/.github/workflows/build_esp.yml +++ b/.github/workflows/build_esp.yml @@ -52,7 +52,7 @@ jobs: - name: Upload Artifacts for Hardware Testing if: matrix.board == 'espressif_s3_devkitc' && github.repository_owner == 'hathach' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{ matrix.board }} path: | diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml index 4c4b12a6b..5dc0f2764 100644 --- a/.github/workflows/cifuzz.yml +++ b/.github/workflows/cifuzz.yml @@ -27,7 +27,7 @@ jobs: language: c++ fuzz-seconds: 600 - name: Upload Crash - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: failure() && steps.build.outcome == 'success' with: name: artifacts diff --git a/.github/workflows/cmake_arm.yml b/.github/workflows/cmake_arm.yml index 80ab1ea71..1edd2e121 100644 --- a/.github/workflows/cmake_arm.yml +++ b/.github/workflows/cmake_arm.yml @@ -93,7 +93,7 @@ jobs: - name: Upload Artifacts for Hardware Testing (rp2040) if: matrix.family == 'rp2040' && github.repository_owner == 'hathach' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: raspberry_pi_pico path: | @@ -101,7 +101,7 @@ jobs: - name: Upload Artifacts for Hardware Testing (nRF) if: matrix.family == 'nrf' && github.repository_owner == 'hathach' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: feather_nrf52840_express path: | @@ -109,7 +109,7 @@ jobs: - name: Upload Artifacts for Hardware Testing (samd51) if: matrix.family == 'samd51' && github.repository_owner == 'hathach' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: itsybitsy_m4 path: | diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 3d51fc5b7..1f7b60b9c 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -130,7 +130,7 @@ jobs: category: "/language:${{matrix.language}}" - name: Archive CodeQL results - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: codeql-results path: ${{ steps.step1.outputs.sarif-output }} From ad5c449f1e37a92b093263680ee772e448100d9c Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 22 Mar 2024 20:12:25 +0700 Subject: [PATCH 157/454] bump up download artifacts to v4 --- .github/workflows/build_esp.yml | 2 +- .github/workflows/cmake_arm.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_esp.yml b/.github/workflows/build_esp.yml index 6106592de..07cbf3552 100644 --- a/.github/workflows/build_esp.yml +++ b/.github/workflows/build_esp.yml @@ -98,7 +98,7 @@ jobs: sparse-checkout: test/hil - name: Download Artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: ${{ matrix.board }} path: cmake-build/cmake-build-${{ matrix.board }} diff --git a/.github/workflows/cmake_arm.yml b/.github/workflows/cmake_arm.yml index 1edd2e121..732e9b9df 100644 --- a/.github/workflows/cmake_arm.yml +++ b/.github/workflows/cmake_arm.yml @@ -153,7 +153,7 @@ jobs: sparse-checkout: test/hil - name: Download Artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: ${{ matrix.board }} path: cmake-build/cmake-build-${{ matrix.board }} From 94c27fcdf77cdc4599df232b7785dfc5d3cc7407 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 22 Mar 2024 20:19:12 +0700 Subject: [PATCH 158/454] skip rp2040 build for cdc_msc_hid_freertos --- examples/host/cdc_msc_hid_freertos/only.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/host/cdc_msc_hid_freertos/only.txt b/examples/host/cdc_msc_hid_freertos/only.txt index 3837ac8a2..81d993ffa 100644 --- a/examples/host/cdc_msc_hid_freertos/only.txt +++ b/examples/host/cdc_msc_hid_freertos/only.txt @@ -6,7 +6,6 @@ mcu:LPC43XX mcu:MIMXRT1XXX mcu:MIMXRT10XX mcu:MIMXRT11XX -mcu:RP2040 mcu:MSP432E4 mcu:RX65X mcu:RAXXX From c8805c61f9b0e3c03d8d3592127b1239a45c9880 Mon Sep 17 00:00:00 2001 From: acscd Date: Fri, 22 Mar 2024 20:05:52 -0500 Subject: [PATCH 159/454] 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); From aba00ed22c6fe9ce5ca636c2909a55ab48c65d14 Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Sat, 23 Mar 2024 22:35:06 +0900 Subject: [PATCH 160/454] Fix the error that occurs when executing make in Windows --- examples/build_system/make/toolchain/arm_gcc.mk | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/build_system/make/toolchain/arm_gcc.mk b/examples/build_system/make/toolchain/arm_gcc.mk index b87657f53..ed5ddc970 100644 --- a/examples/build_system/make/toolchain/arm_gcc.mk +++ b/examples/build_system/make/toolchain/arm_gcc.mk @@ -74,6 +74,8 @@ LDFLAGS += -Wl,--print-memory-usage endif # from version 12 -ifeq ($(shell expr $(CC_VERSION_MAJOR) \>= 12),1) +ifeq ($(strip $(if $(CMDEXE),\ + $(shell if $(CC_VERSION_MAJOR) geq 12 (echo 1) else (echo 0)),\ + $(shell expr $(CC_VERSION_MAJOR) \>= 12))), 1) LDFLAGS += -Wl,--no-warn-rwx-segment endif From 5a880013c8c83c51d8c444dcdf522a1ff778a618 Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Sun, 17 Mar 2024 22:36:09 +0900 Subject: [PATCH 161/454] Add UVC 2ch example --- .../device/video_capture_2ch/CMakeLists.txt | 39 + examples/device/video_capture_2ch/Makefile | 18 + examples/device/video_capture_2ch/skip.txt | 4 + .../video_capture_2ch/src/CMakeLists.txt | 4 + .../device/video_capture_2ch/src/images.h | 1939 +++++++++++++++++ examples/device/video_capture_2ch/src/main.c | 351 +++ .../video_capture_2ch/src/tusb_config.h | 120 + .../video_capture_2ch/src/usb_descriptors.c | 669 ++++++ .../video_capture_2ch/src/usb_descriptors.h | 238 ++ 9 files changed, 3382 insertions(+) create mode 100644 examples/device/video_capture_2ch/CMakeLists.txt create mode 100644 examples/device/video_capture_2ch/Makefile create mode 100644 examples/device/video_capture_2ch/skip.txt create mode 100644 examples/device/video_capture_2ch/src/CMakeLists.txt create mode 100644 examples/device/video_capture_2ch/src/images.h create mode 100644 examples/device/video_capture_2ch/src/main.c create mode 100644 examples/device/video_capture_2ch/src/tusb_config.h create mode 100644 examples/device/video_capture_2ch/src/usb_descriptors.c create mode 100644 examples/device/video_capture_2ch/src/usb_descriptors.h diff --git a/examples/device/video_capture_2ch/CMakeLists.txt b/examples/device/video_capture_2ch/CMakeLists.txt new file mode 100644 index 000000000..80dc39ca5 --- /dev/null +++ b/examples/device/video_capture_2ch/CMakeLists.txt @@ -0,0 +1,39 @@ +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}) + +if (FORCE_READONLY) +target_compile_definitions(${PROJECT} PRIVATE + CFG_EXAMPLE_VIDEO_READONLY +) +endif() + +# 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/video_capture_2ch/Makefile b/examples/device/video_capture_2ch/Makefile new file mode 100644 index 000000000..d698a848d --- /dev/null +++ b/examples/device/video_capture_2ch/Makefile @@ -0,0 +1,18 @@ +include ../../build_system/make/make.mk + +ifeq ($(DISABLE_MJPEG),1) +CFLAGS += -DCFG_EXAMPLE_VIDEO_DISABLE_MJPEG +endif +ifeq ($(FORCE_READONLY),1) +CFLAGS += -DCFG_EXAMPLE_VIDEO_READONLY +endif + +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/video_capture_2ch/skip.txt b/examples/device/video_capture_2ch/skip.txt new file mode 100644 index 000000000..db64cc639 --- /dev/null +++ b/examples/device/video_capture_2ch/skip.txt @@ -0,0 +1,4 @@ +mcu:MSP430x5xx +mcu:NUC121 +mcu:SAMD11 +family:espressif diff --git a/examples/device/video_capture_2ch/src/CMakeLists.txt b/examples/device/video_capture_2ch/src/CMakeLists.txt new file mode 100644 index 000000000..cef2b46ee --- /dev/null +++ b/examples/device/video_capture_2ch/src/CMakeLists.txt @@ -0,0 +1,4 @@ +# This file is for ESP-IDF only +idf_component_register(SRCS "main.c" "usb_descriptors.c" + INCLUDE_DIRS "." + REQUIRES boards tinyusb_src) diff --git a/examples/device/video_capture_2ch/src/images.h b/examples/device/video_capture_2ch/src/images.h new file mode 100644 index 000000000..ac372cb16 --- /dev/null +++ b/examples/device/video_capture_2ch/src/images.h @@ -0,0 +1,1939 @@ +#if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) +// uncopmressed frame +static const unsigned char frame_buffer[128 * (96 + 1) * 2] = { + /* 0 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 1 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 2 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 3 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 4 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 5 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 6 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 7 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 8 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 9 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 10 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 11 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 12 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 13 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 14 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 15 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 16 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 17 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 18 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 19 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 20 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 21 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 22 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 23 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 24 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 25 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 26 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 27 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 28 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 29 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 30 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 31 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 32 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 33 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 34 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 35 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 36 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 37 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 38 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 39 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 40 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 41 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 42 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 43 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 44 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 45 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 46 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 47 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 48 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 49 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 50 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 51 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 52 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 53 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 54 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 55 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 56 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 57 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 58 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 59 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 60 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 61 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 62 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 63 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 64 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 65 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 66 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 67 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 68 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 69 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 70 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 71 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 72 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 73 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 74 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 75 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 76 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 77 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 78 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 79 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 80 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 81 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 82 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 83 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 84 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 85 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 86 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 87 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 88 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 89 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 90 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 91 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 92 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 93 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 94 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 95 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 96 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, +}; + +#else + +// mpeg compressed data (not CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) +#define color_bar_0_jpg_len 511 +#define color_bar_1_jpg_len 512 +#define color_bar_2_jpg_len 511 +#define color_bar_3_jpg_len 511 +#define color_bar_4_jpg_len 511 +#define color_bar_5_jpg_len 512 +#define color_bar_6_jpg_len 511 +#define color_bar_7_jpg_len 511 + +unsigned char color_bar_0_jpg[] = { + 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, + 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, + 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x92, 0x8a, 0x00, + 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, + 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, + 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, + 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, + 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, + 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, + 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, + 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, + 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, + 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, + 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, + 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, + 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, + 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, + 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, + 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, + 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, + 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, + 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, + 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, + 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0xff, 0xd9 +}; +unsigned char color_bar_1_jpg[] = { + 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, + 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, + 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x7d, 0x15, 0x98, + 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, + 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, + 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, + 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, + 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, + 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, + 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, + 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, + 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, + 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, + 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, + 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, + 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, + 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, + 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, + 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, + 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, + 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, + 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, + 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, + 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x7f, 0xff, 0xd9 +}; +unsigned char color_bar_2_jpg[] = { + 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, + 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, + 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x75, 0x14, 0xcc, + 0xc4, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, + 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, + 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, + 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, + 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, + 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, + 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, + 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, + 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, + 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, + 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, + 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, + 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, + 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, + 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, + 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, + 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, + 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, + 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, + 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, + 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x33, 0xff, 0xd9 +}; +unsigned char color_bar_3_jpg[] = { + 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, + 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, + 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x5a, 0x2a, 0x08, + 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, + 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, + 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, + 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, + 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, + 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, + 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, + 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, + 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, + 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, + 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, + 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, + 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, + 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, + 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, + 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, + 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, + 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, + 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, + 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, + 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x91, 0xff, 0xd9 +}; +unsigned char color_bar_4_jpg[] = { + 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, + 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, + 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x4a, 0x2a, 0xcb, + 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, + 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, + 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, + 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, + 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, + 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, + 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, + 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, + 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, + 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, + 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, + 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, + 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, + 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, + 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, + 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, + 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, + 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, + 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, + 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, + 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x9f, 0xff, 0xd9 +}; +unsigned char color_bar_5_jpg[] = { + 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, + 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, + 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x6d, 0x14, 0x8d, + 0x04, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, + 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, + 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, + 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, + 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, + 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, + 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, + 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, + 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, + 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, + 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, + 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, + 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, + 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, + 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, + 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, + 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, + 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, + 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, + 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, + 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x7f, 0xff, 0xd9 +}; +unsigned char color_bar_6_jpg[] = { + 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, + 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, + 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x65, 0x15, 0xa0, + 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, + 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, + 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, + 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, + 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, + 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, + 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, + 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, + 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, + 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, + 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, + 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, + 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, + 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, + 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, + 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, + 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, + 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, + 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, + 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, + 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x33, 0xff, 0xd9 +}; +unsigned char color_bar_7_jpg[] = { + 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, + 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, + 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x8e, 0x8a, 0x00, + 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, + 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, + 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, + 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, + 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, + 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, + 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, + 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, + 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, + 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, + 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, + 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, + 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, + 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, + 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, + 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, + 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, + 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, + 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, + 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, + 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x47, 0xff, 0xd9 +}; +#endif diff --git a/examples/device/video_capture_2ch/src/main.c b/examples/device/video_capture_2ch/src/main.c new file mode 100644 index 000000000..361f52b37 --- /dev/null +++ b/examples/device/video_capture_2ch/src/main.c @@ -0,0 +1,351 @@ +/* + * 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 +#include + +#include "bsp/board_api.h" +#include "tusb.h" +#include "usb_descriptors.h" + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF PROTYPES +//--------------------------------------------------------------------+ + +/* 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; + +void led_blinking_task(void* param); +void usb_device_task(void *param); +void video_task(void* param); + +#if CFG_TUSB_OS == OPT_OS_FREERTOS +void freertos_init_task(void); +#endif + + +//--------------------------------------------------------------------+ +// Main +//--------------------------------------------------------------------+ +int main(void) { + board_init(); + + // If using FreeRTOS: create blinky, tinyusb device, video task +#if CFG_TUSB_OS == OPT_OS_FREERTOS + freertos_init_task(); +#else + // init device stack on configured roothub port + tud_init(BOARD_TUD_RHPORT); + + if (board_init_after_tusb) { + board_init_after_tusb(); + } + + while (1) { + tud_task(); // tinyusb device task + led_blinking_task(NULL); + video_task(NULL); + } +#endif +} + +//--------------------------------------------------------------------+ +// 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; +} + +//--------------------------------------------------------------------+ +// USB Video +//--------------------------------------------------------------------+ +static unsigned frame_num[CFG_TUD_VIDEO_STREAMING] = {1}; +static unsigned tx_busy = 0; +static unsigned interval_ms[CFG_TUD_VIDEO_STREAMING] = {1000 / FRAME_RATE}; + +#ifdef CFG_EXAMPLE_VIDEO_READONLY +// For mcus that does not have enough SRAM for frame buffer, we use fixed frame data. +// To further reduce the size, we use MJPEG format instead of YUY2. +#include "images.h" + +#if !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) +static struct { + uint32_t size; + uint8_t const *buffer; +} const frames[] = { + {color_bar_0_jpg_len, color_bar_0_jpg}, + {color_bar_1_jpg_len, color_bar_1_jpg}, + {color_bar_2_jpg_len, color_bar_2_jpg}, + {color_bar_3_jpg_len, color_bar_3_jpg}, + {color_bar_4_jpg_len, color_bar_4_jpg}, + {color_bar_5_jpg_len, color_bar_5_jpg}, + {color_bar_6_jpg_len, color_bar_6_jpg}, + {color_bar_7_jpg_len, color_bar_7_jpg}, +}; +#endif + +#else + +// YUY2 frame buffer +static uint8_t frame_buffer[2][FRAME_WIDTH * FRAME_HEIGHT * 16 / 8]; + +static void fill_color_bar(uint8_t* buffer, unsigned start_position) { + /* EBU color bars: https://stackoverflow.com/questions/6939422 */ + static uint8_t const bar_color[8][4] = { + /* Y, U, Y, V */ + { 235, 128, 235, 128}, /* 100% White */ + { 219, 16, 219, 138}, /* Yellow */ + { 188, 154, 188, 16}, /* Cyan */ + { 173, 42, 173, 26}, /* Green */ + { 78, 214, 78, 230}, /* Magenta */ + { 63, 102, 63, 240}, /* Red */ + { 32, 240, 32, 118}, /* Blue */ + { 16, 128, 16, 128}, /* Black */ + }; + uint8_t* p; + + /* Generate the 1st line */ + uint8_t* end = &buffer[FRAME_WIDTH * 2]; + unsigned idx = (FRAME_WIDTH / 2 - 1) - (start_position % (FRAME_WIDTH / 2)); + p = &buffer[idx * 4]; + for (unsigned i = 0; i < 8; ++i) { + for (int j = 0; j < FRAME_WIDTH / (2 * 8); ++j) { + memcpy(p, &bar_color[i], 4); + p += 4; + if (end <= p) { + p = buffer; + } + } + } + + /* Duplicate the 1st line to the others */ + p = &buffer[FRAME_WIDTH * 2]; + for (unsigned i = 1; i < FRAME_HEIGHT; ++i) { + memcpy(p, buffer, FRAME_WIDTH * 2); + p += FRAME_WIDTH * 2; + } +} + +#endif + +void video_send_frame(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) { + static unsigned start_ms[CFG_TUD_VIDEO_STREAMING] = {0, }; + static unsigned already_sent = 0; + + uint32_t idx = ctl_idx + stm_idx; + if (!tud_video_n_streaming(ctl_idx, stm_idx)) { + already_sent &= ~(1u << idx); + frame_num[idx] = 0; + return; + } + + if (!(already_sent & (1u << idx))) { + already_sent |= 1u << idx; + tx_busy |= 1u << idx; + start_ms[idx] = board_millis(); +#ifdef CFG_EXAMPLE_VIDEO_READONLY + #if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) + tud_video_n_frame_xfer(ctl_idx, stm_idx, (void*)(uintptr_t)&frame_buffer[(frame_num[idx] % (FRAME_WIDTH / 2)) * 4], + FRAME_WIDTH * FRAME_HEIGHT * 16/8); + #else + tud_video_n_frame_xfer(ctl_idx, stm_idx, (void*)(uintptr_t)frames[frame_num[idx] % 8].buffer, frames[frame_num[idx] % 8].size); + #endif +#else + fill_color_bar(frame_buffer[idx], frame_num[idx]); + tud_video_n_frame_xfer(ctl_idx, stm_idx, (void*) frame_buffer[idx], FRAME_WIDTH * FRAME_HEIGHT * 16 / 8); +#endif + } + + unsigned cur = board_millis(); + if (cur - start_ms[idx] < interval_ms[idx]) return; // not enough time + if (tx_busy & (1u << idx)) return; + start_ms[idx] += interval_ms[idx]; + tx_busy |= 1u << idx; + +#ifdef CFG_EXAMPLE_VIDEO_READONLY + #if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) + tud_video_n_frame_xfer(ctl_idx, stm_idx, (void*)(uintptr_t)&frame_buffer[(frame_num[idx] % (FRAME_WIDTH / 2)) * 4], + FRAME_WIDTH * FRAME_HEIGHT * 16/8); + #else + tud_video_n_frame_xfer(ctl_idx, stm_idx, (void*)(uintptr_t)frames[frame_num[idx] % 8].buffer, frames[frame_num[idx] % 8].size); + #endif +#else + fill_color_bar(frame_buffer[idx], frame_num[idx]); + tud_video_n_frame_xfer(ctl_idx, stm_idx, (void*) frame_buffer[idx], FRAME_WIDTH * FRAME_HEIGHT * 16 / 8); +#endif +} + + +void video_task(void* param) { + (void) param; + + while(1) { + video_send_frame(0, 0); + video_send_frame(1, 0); + + #if CFG_TUSB_OS == OPT_OS_FREERTOS + vTaskDelay(interval_ms[0] / portTICK_PERIOD_MS); + #else + return; + #endif + } +} + +void tud_video_frame_xfer_complete_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) { + uint32_t idx = ctl_idx + stm_idx; + tx_busy &= ~(1u << idx); + /* flip buffer */ + ++frame_num[idx]; +} + +int tud_video_commit_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, + video_probe_and_commit_control_t const* parameters) { + uint32_t idx = ctl_idx + stm_idx; + /* convert unit to ms from 100 ns */ + interval_ms[idx] = parameters->dwFrameInterval / 10000; + return VIDEO_ERROR_NONE; +} + +//--------------------------------------------------------------------+ +// Blinking Task +//--------------------------------------------------------------------+ +void led_blinking_task(void* param) { + (void) param; + static uint32_t start_ms = 0; + static bool led_state = false; + + while (1) { + #if CFG_TUSB_OS == OPT_OS_FREERTOS + vTaskDelay(blink_interval_ms / portTICK_PERIOD_MS); + #else + if (board_millis() - start_ms < blink_interval_ms) return; // not enough time + #endif + + start_ms += blink_interval_ms; + board_led_write(led_state); + led_state = 1 - led_state; // toggle + } +} + +//--------------------------------------------------------------------+ +// FreeRTOS +//--------------------------------------------------------------------+ +#if CFG_TUSB_OS == OPT_OS_FREERTOS + +#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) + #define USBD_STACK_SIZE 4096 + int main(void); + void app_main(void) { + main(); + } +#else + // Increase stack size when debug log is enabled + #define USBD_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1) +#endif + +// 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 video_stack[VIDEO_STACK_SIZE]; +StaticTask_t video_taskdef; +#endif + +// USB Device Driver task +// This top level thread process all usb events and invoke callbacks +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. + tud_init(BOARD_TUD_RHPORT); + + if (board_init_after_tusb) { + board_init_after_tusb(); + } + + // RTOS forever loop + while (1) { + // put this thread to waiting state until there is new events + tud_task(); + } +} + +void freertos_init_task(void) { + #if configSUPPORT_STATIC_ALLOCATION + xTaskCreateStatic(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, blinky_stack, &blinky_taskdef); + xTaskCreateStatic(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_device_stack, &usb_device_taskdef); + xTaskCreateStatic(video_task, "cdc", VIDEO_STACK_SIZE, NULL, configMAX_PRIORITIES - 2, video_stack, &video_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(video_task, "video", VIDEO_STACK_SZIE, NULL, configMAX_PRIORITIES - 2, NULL); + #endif + + // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3 + #if !TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) + vTaskStartScheduler(); + #endif +} +#endif diff --git a/examples/device/video_capture_2ch/src/tusb_config.h b/examples/device/video_capture_2ch/src/tusb_config.h new file mode 100644 index 000000000..fe66d63b5 --- /dev/null +++ b/examples/device/video_capture_2ch/src/tusb_config.h @@ -0,0 +1,120 @@ +/* + * 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 + +//-------------------------------------------------------------------- +// 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 + +// 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 + +// 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 +//-------------------------------------------------------------------- + +#ifndef CFG_TUD_ENDPOINT0_SIZE +#define CFG_TUD_ENDPOINT0_SIZE 64 +#endif + +//------------- CLASS -------------// +// The number of video control interfaces +#define CFG_TUD_VIDEO 2 + +// The number of video streaming interfaces +#define CFG_TUD_VIDEO_STREAMING 2 + +// video streaming endpoint buffer size +#define CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE 256 + +// use bulk endpoint for streaming interface +#define CFG_TUD_VIDEO_STREAMING_BULK 1 + +//#define CFG_EXAMPLE_VIDEO_READONLY +//#define CFG_EXAMPLE_VIDEO_DISABLE_MJPEG + +#define CFG_TUD_VIDEO_LOG_LEVEL 1 + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_CONFIG_H_ */ diff --git a/examples/device/video_capture_2ch/src/usb_descriptors.c b/examples/device/video_capture_2ch/src/usb_descriptors.c new file mode 100644 index 000000000..0c1066416 --- /dev/null +++ b/examples/device/video_capture_2ch/src/usb_descriptors.c @@ -0,0 +1,669 @@ +/* + * 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" +#include "usb_descriptors.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] VIDEO | 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(VIDEO, 5) | _PID_MAP(VENDOR, 6) ) + +#define USB_VID 0xCafe +#define USB_BCD 0x0200 + +// String Descriptor Index +enum { + STRID_LANGID = 0, + STRID_MANUFACTURER, + STRID_PRODUCT, + STRID_SERIAL, + STRID_UVC_CONTROL_1, + STRID_UVC_STREAMING_1, + STRID_UVC_CONTROL_2, + STRID_UVC_STREAMING_2, +}; + +// 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 UVC Control 1", // 4: UVC Interface 1 + "TinyUSB UVC Streaming 1", // 5: UVC Interface 1 + "TinyUSB UVC Control 2", // 6: UVC Interface 2 + "TinyUSB UVC Streaming 2", // 7: UVC Interface 2 +}; + +//--------------------------------------------------------------------+ +// 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 Video + // 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 = STRID_MANUFACTURER, + .iProduct = STRID_PRODUCT, + .iSerialNumber = STRID_SERIAL, + + .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 +//--------------------------------------------------------------------+ + +/* Time stamp base clock. It is a deprecated parameter. */ +#define UVC_CLOCK_FREQUENCY 27000000 + +/* video capture path */ +#define UVC_ENTITY_CAP_INPUT_TERMINAL 0x01 +#define UVC_ENTITY_CAP_OUTPUT_TERMINAL 0x02 + +enum { + ITF_NUM_VIDEO_CONTROL_1, + ITF_NUM_VIDEO_STREAMING_1, + ITF_NUM_VIDEO_CONTROL_2, + ITF_NUM_VIDEO_STREAMING_2, + ITF_NUM_TOTAL +}; + +#define EPNUM_VIDEO_IN_1 0x81 +#define EPNUM_VIDEO_IN_2 0x82 + +#if defined(CFG_EXAMPLE_VIDEO_READONLY) && !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) + #define USE_MJPEG 1 +#else + #define USE_MJPEG 0 +#endif + +#define USE_ISO_STREAMING (!CFG_TUD_VIDEO_STREAMING_BULK) + +typedef struct TU_ATTR_PACKED { + tusb_desc_interface_t itf; + tusb_desc_video_control_header_1itf_t header; + tusb_desc_video_control_camera_terminal_t camera_terminal; + tusb_desc_video_control_output_terminal_t output_terminal; +} uvc_control_desc_t; + +/* Windows support YUY2 and NV12 + * https://docs.microsoft.com/en-us/windows-hardware/drivers/stream/usb-video-class-driver-overview */ + +typedef struct TU_ATTR_PACKED { + tusb_desc_interface_t itf; + tusb_desc_video_streaming_input_header_1byte_t header; + +#if USE_MJPEG + tusb_desc_video_format_mjpeg_t format; + tusb_desc_video_frame_mjpeg_continuous_t frame; +#else + tusb_desc_video_format_uncompressed_t format; + tusb_desc_video_frame_uncompressed_continuous_t frame; +#endif + + tusb_desc_video_streaming_color_matching_t color; + +#if USE_ISO_STREAMING + // For ISO streaming, USB spec requires to alternate interface + tusb_desc_interface_t itf_alt; +#endif + + tusb_desc_endpoint_t ep; +} uvc_streaming_desc_t; + +typedef struct TU_ATTR_PACKED { + tusb_desc_configuration_t config; + struct TU_ATTR_PACKED { + tusb_desc_interface_assoc_t iad; + uvc_control_desc_t video_control; + uvc_streaming_desc_t video_streaming; + } uvc[2]; +} uvc_cfg_desc_t; + +const uvc_cfg_desc_t desc_fs_configuration = { + .config = { + .bLength = sizeof(tusb_desc_configuration_t), + .bDescriptorType = TUSB_DESC_CONFIGURATION, + + .wTotalLength = sizeof(uvc_cfg_desc_t), + .bNumInterfaces = ITF_NUM_TOTAL, + .bConfigurationValue = 1, + .iConfiguration = 0, + .bmAttributes = TU_BIT(7), + .bMaxPower = 100 / 2 + }, + .uvc = { + { + .iad = { + .bLength = sizeof(tusb_desc_interface_assoc_t), + .bDescriptorType = TUSB_DESC_INTERFACE_ASSOCIATION, + + .bFirstInterface = ITF_NUM_VIDEO_CONTROL_1, + .bInterfaceCount = 2, + .bFunctionClass = TUSB_CLASS_VIDEO, + .bFunctionSubClass = VIDEO_SUBCLASS_INTERFACE_COLLECTION, + .bFunctionProtocol = VIDEO_ITF_PROTOCOL_UNDEFINED, + .iFunction = 0 + }, + + .video_control = { + .itf = { + .bLength = sizeof(tusb_desc_interface_t), + .bDescriptorType = TUSB_DESC_INTERFACE, + + .bInterfaceNumber = ITF_NUM_VIDEO_CONTROL_1, + .bAlternateSetting = 0, + .bNumEndpoints = 0, + .bInterfaceClass = TUSB_CLASS_VIDEO, + .bInterfaceSubClass = VIDEO_SUBCLASS_CONTROL, + .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, + .iInterface = STRID_UVC_CONTROL_1 + }, + .header = { + .bLength = sizeof(tusb_desc_video_control_header_1itf_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VC_HEADER, + + .bcdUVC = VIDEO_BCD_1_50, + .wTotalLength = sizeof(uvc_control_desc_t) - sizeof(tusb_desc_interface_t), // CS VC descriptors only + .dwClockFrequency = UVC_CLOCK_FREQUENCY, + .bInCollection = 1, + .baInterfaceNr = { ITF_NUM_VIDEO_STREAMING_1 } + }, + .camera_terminal = { + .bLength = sizeof(tusb_desc_video_control_camera_terminal_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VC_INPUT_TERMINAL, + + .bTerminalID = UVC_ENTITY_CAP_INPUT_TERMINAL, + .wTerminalType = VIDEO_ITT_CAMERA, + .bAssocTerminal = 0, + .iTerminal = 0, + .wObjectiveFocalLengthMin = 0, + .wObjectiveFocalLengthMax = 0, + .wOcularFocalLength = 0, + .bControlSize = 3, + .bmControls = { 0, 0, 0 } + }, + .output_terminal = { + .bLength = sizeof(tusb_desc_video_control_output_terminal_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VC_OUTPUT_TERMINAL, + + .bTerminalID = UVC_ENTITY_CAP_OUTPUT_TERMINAL, + .wTerminalType = VIDEO_TT_STREAMING, + .bAssocTerminal = 0, + .bSourceID = UVC_ENTITY_CAP_INPUT_TERMINAL, + .iTerminal = 0 + } + }, + + .video_streaming = { + .itf = { + .bLength = sizeof(tusb_desc_interface_t), + .bDescriptorType = TUSB_DESC_INTERFACE, + + .bInterfaceNumber = ITF_NUM_VIDEO_STREAMING_1, + .bAlternateSetting = 0, + .bNumEndpoints = CFG_TUD_VIDEO_STREAMING_BULK, // bulk 1, iso 0 + .bInterfaceClass = TUSB_CLASS_VIDEO, + .bInterfaceSubClass = VIDEO_SUBCLASS_STREAMING, + .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, + .iInterface = STRID_UVC_STREAMING_1 + }, + .header = { + .bLength = sizeof(tusb_desc_video_streaming_input_header_1byte_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_INPUT_HEADER, + + .bNumFormats = 1, + .wTotalLength = sizeof(uvc_streaming_desc_t) - sizeof(tusb_desc_interface_t) + - sizeof(tusb_desc_endpoint_t) - (USE_ISO_STREAMING ? sizeof(tusb_desc_interface_t) : 0) , // CS VS descriptors only + .bEndpointAddress = EPNUM_VIDEO_IN_1, + .bmInfo = 0, + .bTerminalLink = UVC_ENTITY_CAP_OUTPUT_TERMINAL, + .bStillCaptureMethod = 0, + .bTriggerSupport = 0, + .bTriggerUsage = 0, + .bControlSize = 1, + .bmaControls = { 0 } + }, + .format = { +#if USE_MJPEG + .bLength = sizeof(tusb_desc_video_format_mjpeg_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_FORMAT_MJPEG, + .bFormatIndex = 1, // 1-based index + .bNumFrameDescriptors = 1, + .bmFlags = 0, +#else + .bLength = sizeof(tusb_desc_video_format_uncompressed_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED, + .bFormatIndex = 1, // 1-based index + .bNumFrameDescriptors = 1, + .guidFormat = { TUD_VIDEO_GUID_YUY2 }, + .bBitsPerPixel = 16, +#endif + .bDefaultFrameIndex = 1, + .bAspectRatioX = 0, + .bAspectRatioY = 0, + .bmInterlaceFlags = 0, + .bCopyProtect = 0 + }, + .frame = { +#if USE_MJPEG + .bLength = sizeof(tusb_desc_video_frame_mjpeg_continuous_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_FRAME_MJPEG, +#else + .bLength = sizeof(tusb_desc_video_frame_uncompressed_continuous_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED, +#endif + .bFrameIndex = 1, // 1-based index + .bmCapabilities = 0, + .wWidth = FRAME_WIDTH, + .wHeight = FRAME_HEIGHT, + .dwMinBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * 1, + .dwMaxBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * FRAME_RATE, + .dwMaxVideoFrameBufferSize = FRAME_WIDTH * FRAME_HEIGHT * 16 / 8, + .dwDefaultFrameInterval = 10000000 / FRAME_RATE, + .bFrameIntervalType = 0, // continuous + .dwFrameInterval = { + 10000000 / FRAME_RATE, // min + 10000000, // max + 10000000 / FRAME_RATE // step + } + }, + .color = { + .bLength = sizeof(tusb_desc_video_streaming_color_matching_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_COLORFORMAT, + + .bColorPrimaries = VIDEO_COLOR_PRIMARIES_BT709, + .bTransferCharacteristics = VIDEO_COLOR_XFER_CH_BT709, + .bMatrixCoefficients = VIDEO_COLOR_COEF_SMPTE170M + }, + +#if USE_ISO_STREAMING + .itf_alt = { + .bLength = sizeof(tusb_desc_interface_t), + .bDescriptorType = TUSB_DESC_INTERFACE, + + .bInterfaceNumber = ITF_NUM_VIDEO_STREAMING_1, + .bAlternateSetting = 1, + .bNumEndpoints = 1, + .bInterfaceClass = TUSB_CLASS_VIDEO, + .bInterfaceSubClass = VIDEO_SUBCLASS_STREAMING, + .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, + .iInterface = STRID_UVC_STREAMING_1 + }, +#endif + + .ep = { + .bLength = sizeof(tusb_desc_endpoint_t), + .bDescriptorType = TUSB_DESC_ENDPOINT, + + .bEndpointAddress = EPNUM_VIDEO_IN_1, + .bmAttributes = { + .xfer = CFG_TUD_VIDEO_STREAMING_BULK ? TUSB_XFER_BULK : TUSB_XFER_ISOCHRONOUS, + .sync = CFG_TUD_VIDEO_STREAMING_BULK ? 0 : 1 // asynchronous + }, + .wMaxPacketSize = CFG_TUD_VIDEO_STREAMING_BULK ? 64 : CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE, + .bInterval = 1 + } + } + }, + { + .iad = { + .bLength = sizeof(tusb_desc_interface_assoc_t), + .bDescriptorType = TUSB_DESC_INTERFACE_ASSOCIATION, + + .bFirstInterface = ITF_NUM_VIDEO_CONTROL_2, + .bInterfaceCount = 2, + .bFunctionClass = TUSB_CLASS_VIDEO, + .bFunctionSubClass = VIDEO_SUBCLASS_INTERFACE_COLLECTION, + .bFunctionProtocol = VIDEO_ITF_PROTOCOL_UNDEFINED, + .iFunction = 0 + }, + + .video_control = { + .itf = { + .bLength = sizeof(tusb_desc_interface_t), + .bDescriptorType = TUSB_DESC_INTERFACE, + + .bInterfaceNumber = ITF_NUM_VIDEO_CONTROL_2, + .bAlternateSetting = 0, + .bNumEndpoints = 0, + .bInterfaceClass = TUSB_CLASS_VIDEO, + .bInterfaceSubClass = VIDEO_SUBCLASS_CONTROL, + .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, + .iInterface = STRID_UVC_CONTROL_2 + }, + .header = { + .bLength = sizeof(tusb_desc_video_control_header_1itf_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VC_HEADER, + + .bcdUVC = VIDEO_BCD_1_50, + .wTotalLength = sizeof(uvc_control_desc_t) - sizeof(tusb_desc_interface_t), // CS VC descriptors only + .dwClockFrequency = UVC_CLOCK_FREQUENCY, + .bInCollection = 1, + .baInterfaceNr = { ITF_NUM_VIDEO_STREAMING_2 } + }, + .camera_terminal = { + .bLength = sizeof(tusb_desc_video_control_camera_terminal_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VC_INPUT_TERMINAL, + + .bTerminalID = UVC_ENTITY_CAP_INPUT_TERMINAL, + .wTerminalType = VIDEO_ITT_CAMERA, + .bAssocTerminal = 0, + .iTerminal = 0, + .wObjectiveFocalLengthMin = 0, + .wObjectiveFocalLengthMax = 0, + .wOcularFocalLength = 0, + .bControlSize = 3, + .bmControls = { 0, 0, 0 } + }, + .output_terminal = { + .bLength = sizeof(tusb_desc_video_control_output_terminal_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VC_OUTPUT_TERMINAL, + + .bTerminalID = UVC_ENTITY_CAP_OUTPUT_TERMINAL, + .wTerminalType = VIDEO_TT_STREAMING, + .bAssocTerminal = 0, + .bSourceID = UVC_ENTITY_CAP_INPUT_TERMINAL, + .iTerminal = 0 + } + }, + + .video_streaming = { + .itf = { + .bLength = sizeof(tusb_desc_interface_t), + .bDescriptorType = TUSB_DESC_INTERFACE, + + .bInterfaceNumber = ITF_NUM_VIDEO_STREAMING_2, + .bAlternateSetting = 0, + .bNumEndpoints = CFG_TUD_VIDEO_STREAMING_BULK, // bulk 1, iso 0 + .bInterfaceClass = TUSB_CLASS_VIDEO, + .bInterfaceSubClass = VIDEO_SUBCLASS_STREAMING, + .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, + .iInterface = STRID_UVC_STREAMING_2 + }, + .header = { + .bLength = sizeof(tusb_desc_video_streaming_input_header_1byte_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_INPUT_HEADER, + + .bNumFormats = 1, + .wTotalLength = sizeof(uvc_streaming_desc_t) - sizeof(tusb_desc_interface_t) + - sizeof(tusb_desc_endpoint_t) - (USE_ISO_STREAMING ? sizeof(tusb_desc_interface_t) : 0) , // CS VS descriptors only + .bEndpointAddress = EPNUM_VIDEO_IN_2, + .bmInfo = 0, + .bTerminalLink = UVC_ENTITY_CAP_OUTPUT_TERMINAL, + .bStillCaptureMethod = 0, + .bTriggerSupport = 0, + .bTriggerUsage = 0, + .bControlSize = 1, + .bmaControls = { 0 } + }, + .format = { +#if USE_MJPEG + .bLength = sizeof(tusb_desc_video_format_mjpeg_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_FORMAT_MJPEG, + .bFormatIndex = 1, // 1-based index + .bNumFrameDescriptors = 1, + .bmFlags = 0, +#else + .bLength = sizeof(tusb_desc_video_format_uncompressed_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED, + .bFormatIndex = 1, // 1-based index + .bNumFrameDescriptors = 1, + .guidFormat = { TUD_VIDEO_GUID_YUY2 }, + .bBitsPerPixel = 16, +#endif + .bDefaultFrameIndex = 1, + .bAspectRatioX = 0, + .bAspectRatioY = 0, + .bmInterlaceFlags = 0, + .bCopyProtect = 0 + }, + .frame = { +#if USE_MJPEG + .bLength = sizeof(tusb_desc_video_frame_mjpeg_continuous_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_FRAME_MJPEG, +#else + .bLength = sizeof(tusb_desc_video_frame_uncompressed_continuous_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED, +#endif + .bFrameIndex = 1, // 1-based index + .bmCapabilities = 0, + .wWidth = FRAME_WIDTH, + .wHeight = FRAME_HEIGHT, + .dwMinBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * 1, + .dwMaxBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * FRAME_RATE, + .dwMaxVideoFrameBufferSize = FRAME_WIDTH * FRAME_HEIGHT * 16 / 8, + .dwDefaultFrameInterval = 10000000 / FRAME_RATE, + .bFrameIntervalType = 0, // continuous + .dwFrameInterval = { + 10000000 / FRAME_RATE, // min + 10000000, // max + 10000000 / FRAME_RATE // step + } + }, + .color = { + .bLength = sizeof(tusb_desc_video_streaming_color_matching_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_COLORFORMAT, + + .bColorPrimaries = VIDEO_COLOR_PRIMARIES_BT709, + .bTransferCharacteristics = VIDEO_COLOR_XFER_CH_BT709, + .bMatrixCoefficients = VIDEO_COLOR_COEF_SMPTE170M + }, + +#if USE_ISO_STREAMING + .itf_alt = { + .bLength = sizeof(tusb_desc_interface_t), + .bDescriptorType = TUSB_DESC_INTERFACE, + + .bInterfaceNumber = ITF_NUM_VIDEO_STREAMING_2, + .bAlternateSetting = 1, + .bNumEndpoints = 1, + .bInterfaceClass = TUSB_CLASS_VIDEO, + .bInterfaceSubClass = VIDEO_SUBCLASS_STREAMING, + .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, + .iInterface = STRID_UVC_STREAMING_2 + }, +#endif + + .ep = { + .bLength = sizeof(tusb_desc_endpoint_t), + .bDescriptorType = TUSB_DESC_ENDPOINT, + + .bEndpointAddress = EPNUM_VIDEO_IN_2, + .bmAttributes = { + .xfer = CFG_TUD_VIDEO_STREAMING_BULK ? TUSB_XFER_BULK : TUSB_XFER_ISOCHRONOUS, + .sync = CFG_TUD_VIDEO_STREAMING_BULK ? 0 : 1 // asynchronous + }, + .wMaxPacketSize = CFG_TUD_VIDEO_STREAMING_BULK ? 64 : CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE, + .bInterval = 1 + } + } + } + } +}; + +#if TUD_OPT_HIGH_SPEED +uvc_cfg_desc_t desc_hs_configuration; + +static uint8_t * get_hs_configuration_desc(void) { + static bool init = false; + + if (!init) { + desc_hs_configuration = desc_fs_configuration; + // change endpoint bulk size to 512 if bulk streaming + if (CFG_TUD_VIDEO_STREAMING_BULK) { + desc_hs_configuration.video_streaming.ep.wMaxPacketSize = 512; + } + } + init = true; + + return (uint8_t *) &desc_hs_configuration; +} + +// 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_t), + .bDescriptorType = TUSB_DESC_DEVICE, + .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 + if (tud_speed_get() == TUSB_SPEED_HIGH) { + return (uint8_t const*) &desc_fs_configuration; + } else { + return get_hs_configuration_desc(); + } +} +#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. + if (tud_speed_get() == TUSB_SPEED_HIGH) { + return get_hs_configuration_desc(); + } else +#endif + { + return (uint8_t const*) &desc_fs_configuration; + } +} + +//--------------------------------------------------------------------+ +// String Descriptors +//--------------------------------------------------------------------+ + +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/video_capture_2ch/src/usb_descriptors.h b/examples/device/video_capture_2ch/src/usb_descriptors.h new file mode 100644 index 000000000..12d41b2f3 --- /dev/null +++ b/examples/device/video_capture_2ch/src/usb_descriptors.h @@ -0,0 +1,238 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 Jerzy Kasenbreg + * Copyright (c) 2021 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. + * + */ + +#ifndef _USB_DESCRIPTORS_H_ +#define _USB_DESCRIPTORS_H_ + +#define FRAME_WIDTH 128 +#define FRAME_HEIGHT 96 +#define FRAME_RATE 10 + +// NOTE: descriptor template is not used but leave here as reference + +#define TUD_VIDEO_CAPTURE_DESC_UNCOMPR_LEN (\ + TUD_VIDEO_DESC_IAD_LEN\ + /* control */\ + + TUD_VIDEO_DESC_STD_VC_LEN\ + + (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\ + + TUD_VIDEO_DESC_CAMERA_TERM_LEN\ + + TUD_VIDEO_DESC_OUTPUT_TERM_LEN\ + /* Interface 1, Alternate 0 */\ + + TUD_VIDEO_DESC_STD_VS_LEN\ + + (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\ + + TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN\ + + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN\ + + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\ + /* Interface 1, Alternate 1 */\ + + TUD_VIDEO_DESC_STD_VS_LEN\ + + 7/* Endpoint */\ + ) + +#define TUD_VIDEO_CAPTURE_DESC_MJPEG_LEN (\ + TUD_VIDEO_DESC_IAD_LEN\ + /* control */\ + + TUD_VIDEO_DESC_STD_VC_LEN\ + + (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\ + + TUD_VIDEO_DESC_CAMERA_TERM_LEN\ + + TUD_VIDEO_DESC_OUTPUT_TERM_LEN\ + /* Interface 1, Alternate 0 */\ + + TUD_VIDEO_DESC_STD_VS_LEN\ + + (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\ + + TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN\ + + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN\ + + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\ + /* Interface 1, Alternate 1 */\ + + TUD_VIDEO_DESC_STD_VS_LEN\ + + 7/* Endpoint */\ + ) + +#define TUD_VIDEO_CAPTURE_DESC_UNCOMPR_BULK_LEN (\ + TUD_VIDEO_DESC_IAD_LEN\ + /* control */\ + + TUD_VIDEO_DESC_STD_VC_LEN\ + + (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\ + + TUD_VIDEO_DESC_CAMERA_TERM_LEN\ + + TUD_VIDEO_DESC_OUTPUT_TERM_LEN\ + /* Interface 1, Alternate 0 */\ + + TUD_VIDEO_DESC_STD_VS_LEN\ + + (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\ + + TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN\ + + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN\ + + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\ + + 7/* Endpoint */\ + ) + +#define TUD_VIDEO_CAPTURE_DESC_MJPEG_BULK_LEN (\ + TUD_VIDEO_DESC_IAD_LEN\ + /* control */\ + + TUD_VIDEO_DESC_STD_VC_LEN\ + + (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\ + + TUD_VIDEO_DESC_CAMERA_TERM_LEN\ + + TUD_VIDEO_DESC_OUTPUT_TERM_LEN\ + /* Interface 1, Alternate 0 */\ + + TUD_VIDEO_DESC_STD_VS_LEN\ + + (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\ + + TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN\ + + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN\ + + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\ + + 7/* Endpoint */\ + ) + +/* Windows support YUY2 and NV12 + * https://docs.microsoft.com/en-us/windows-hardware/drivers/stream/usb-video-class-driver-overview */ + +#define TUD_VIDEO_DESC_CS_VS_FMT_YUY2(_fmtidx, _numfmtdesc, _frmidx, _asrx, _asry, _interlace, _cp) \ + TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR(_fmtidx, _numfmtdesc, TUD_VIDEO_GUID_YUY2, 16, _frmidx, _asrx, _asry, _interlace, _cp) +#define TUD_VIDEO_DESC_CS_VS_FMT_NV12(_fmtidx, _numfmtdesc, _frmidx, _asrx, _asry, _interlace, _cp) \ + TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR(_fmtidx, _numfmtdesc, TUD_VIDEO_GUID_NV12, 12, _frmidx, _asrx, _asry, _interlace, _cp) +#define TUD_VIDEO_DESC_CS_VS_FMT_M420(_fmtidx, _numfmtdesc, _frmidx, _asrx, _asry, _interlace, _cp) \ + TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR(_fmtidx, _numfmtdesc, TUD_VIDEO_GUID_M420, 12, _frmidx, _asrx, _asry, _interlace, _cp) +#define TUD_VIDEO_DESC_CS_VS_FMT_I420(_fmtidx, _numfmtdesc, _frmidx, _asrx, _asry, _interlace, _cp) \ + TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR(_fmtidx, _numfmtdesc, TUD_VIDEO_GUID_I420, 12, _frmidx, _asrx, _asry, _interlace, _cp) + +#define TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR(_stridx, _epin, _width, _height, _fps, _epsize) \ + TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \ + /* Video control 0 */ \ + TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ + /* Header: UVC 1.5, length of followed descs, clock (deprecated), streaming interfaces */ \ + TUD_VIDEO_DESC_CS_VC(0x0150, TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ + /* Camera Terminal: ID, bAssocTerminal, iTerminal, focal min, max, length, bmControl */ \ + TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0, 0, 0, 0, 0), \ + TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \ + /* Video stream alt. 0 */ \ + TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 0, _stridx), \ + /* Video stream header for without still image capture */ \ + TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ + /*wTotalLength - bLength */ TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ + _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ + /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ + /*bmaControls(1)*/0), \ + /* Video stream format */ \ + TUD_VIDEO_DESC_CS_VS_FMT_YUY2(/*bFormatIndex*/1, /*bNumFrameDescriptors*/1, \ + /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0), \ + /* Video stream frame format */ \ + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT(/*bFrameIndex */1, 0, _width, _height, \ + _width * _height * 16, _width * _height * 16 * _fps, \ + _width * _height * 16 / 8, \ + (10000000/_fps), (10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \ + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \ + /* VS alt 1 */\ + TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 1, 1, _stridx), \ + /* EP */ \ + TUD_VIDEO_DESC_EP_ISO(_epin, _epsize, 1) + +#define TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG(_stridx, _epin, _width, _height, _fps, _epsize) \ + TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \ + /* Video control 0 */ \ + TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ + /* Header: UVC 1.5, length of followed descs, clock (deprecated), streaming interfaces */ \ + TUD_VIDEO_DESC_CS_VC(0x0150, TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ + /* Camera Terminal: ID, bAssocTerminal, iTerminal, focal min, max, length, bmControl */ \ + TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0, 0, 0, 0, 0), \ + TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \ + /* Video stream alt. 0 */ \ + TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 0, _stridx), \ + /* Video stream header for without still image capture */ \ + TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ + /*wTotalLength - bLength */ TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ + _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ + /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ + /*bmaControls(1)*/0), \ + /* Video stream format */ \ + TUD_VIDEO_DESC_CS_VS_FMT_MJPEG(/*bFormatIndex*/1, /*bNumFrameDescriptors*/1, \ + /*bmFlags*/0, /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0), \ + /* Video stream frame format */ \ + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT(/*bFrameIndex */1, 0, _width, _height, \ + _width * _height * 16, _width * _height * 16 * _fps, \ + _width * _height * 16 / 8, \ + (10000000/_fps), (10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \ + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \ + /* VS alt 1 */\ + TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 1, 1, _stridx), \ + /* EP */ \ + TUD_VIDEO_DESC_EP_ISO(_epin, _epsize, 1) + + +#define TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR_BULK(_stridx, _epin, _width, _height, _fps, _epsize) \ + TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \ + /* Video control 0 */ \ + TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ + /* Header: UVC 1.5, length of followed descs, clock (deprecated), streaming interfaces */ \ + TUD_VIDEO_DESC_CS_VC(0x0150, TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ + /* Camera Terminal: ID, bAssocTerminal, iTerminal, focal min, max, length, bmControl */ \ + TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0, 0, 0, 0, 0), \ + TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \ + /* Video stream alt. 0 */ \ + TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 1, _stridx), \ + /* Video stream header for without still image capture */ \ + TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ + /*wTotalLength - bLength */\ + TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ + _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ + /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ + /*bmaControls(1)*/0), \ + /* Video stream format */ \ + TUD_VIDEO_DESC_CS_VS_FMT_YUY2(/*bFormatIndex*/1, /*bNumFrameDescriptors*/1, \ + /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0), \ + /* Video stream frame format */ \ + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT(/*bFrameIndex */1, 0, _width, _height, \ + _width * _height * 16, _width * _height * 16 * _fps, \ + _width * _height * 16 / 8, \ + (10000000/_fps), (10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \ + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \ + TUD_VIDEO_DESC_EP_BULK(_epin, _epsize, 1) + +#define TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG_BULK(_stridx, _epin, _width, _height, _fps, _epsize) \ + TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \ + /* Video control 0 */ \ + TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ + /* Header: UVC 1.5, length of followed descs, clock (deprecated), streaming interfaces */ \ + TUD_VIDEO_DESC_CS_VC(0x0150, TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ + /* Camera Terminal: ID, bAssocTerminal, iTerminal, focal min, max, length, bmControl */ \ + TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0, 0, 0, 0, 0), \ + TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, UVC_ENTITY_CAP_INPUT_TERMINAL, 0), \ + /* Video stream alt. 0 */ \ + TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 1, _stridx), \ + /* Video stream header for without still image capture */ \ + TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ + /*wTotalLength - bLength */ TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ + _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ + /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ + /*bmaControls(1)*/0), \ + /* Video stream format */ \ + TUD_VIDEO_DESC_CS_VS_FMT_MJPEG(/*bFormatIndex*/1, /*bNumFrameDescriptors*/1, \ + /*bmFlags*/0, /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0), \ + /* Video stream frame format */ \ + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT(/*bFrameIndex */1, 0, _width, _height, \ + _width * _height * 16, _width * _height * 16 * _fps, \ + _width * _height * 16 / 8, \ + (10000000/_fps), (10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \ + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \ + /* EP */ \ + TUD_VIDEO_DESC_EP_BULK(_epin, _epsize, 1) + + +#endif From a555266174acd639b0734fe2c3c65296450c4182 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 25 Mar 2024 13:54:35 +0700 Subject: [PATCH 162/454] add new labeler workflow --- .github/workflows/labeler.yml | 63 +++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 .github/workflows/labeler.yml diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml new file mode 100644 index 000000000..b4a2cdafa --- /dev/null +++ b/.github/workflows/labeler.yml @@ -0,0 +1,63 @@ +name: Labeler + +on: + issues: + types: [opened] + pull_request: + types: [opened] + +jobs: + label-priority: + runs-on: ubuntu-latest + + steps: + - name: Label New Issue or PR + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.API_TOKEN_GITHUB }} + script: | + let label = ''; + let username = ''; + let issueOrPrNumber = 0; + + if (context.eventName === 'issues') { + username = context.payload.issue.user.login; + issueOrPrNumber = context.payload.issue.number; + } else if (context.eventName === 'pull_request') { + username = context.payload.pull_request.user.login; + issueOrPrNumber = context.payload.pull_request.number; + } + + // Check for Adafruit membership + const adafruitResponse = await github.rest.orgs.checkMembershipForUser({ + org: 'adafruit', + username: username + }); + + if (adafruitResponse.status === 204) { + console.log('Adafruit Member'); + label = 'Prio Urgent'; + } else { + // Check if the user is a contributor + const collaboratorResponse = await github.rest.repos.checkCollaborator({ + owner: context.repo.owner, + repo: context.repo.repo, + username: username + }); + + if (collaboratorResponse.status === 204) { + console.log('Contributor'); + label = 'Prio Higher'; + } else { + console.log('Not a contributor or Adafruit member'); + } + } + + if (label !== '') { + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issueOrPrNumber, + labels: [label] + }); + } From a7a65e5d6d43fbb0c07eb82b3ab9fd8286dd3013 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 25 Mar 2024 18:30:03 +0700 Subject: [PATCH 163/454] add delete API for rtthread --- src/osal/osal_rtthread.h | 54 ++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/src/osal/osal_rtthread.h b/src/osal/osal_rtthread.h index a8423086f..c27814835 100644 --- a/src/osal/osal_rtthread.h +++ b/src/osal/osal_rtthread.h @@ -48,23 +48,27 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) { typedef struct rt_semaphore osal_semaphore_def_t; typedef rt_sem_t osal_semaphore_t; -TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t -osal_semaphore_create(osal_semaphore_def_t *semdef) { - rt_sem_init(semdef, "tusb", 0, RT_IPC_FLAG_PRIO); - return semdef; +TU_ATTR_ALWAYS_INLINE static inline +osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t *semdef) { + rt_sem_init(semdef, "tusb", 0, RT_IPC_FLAG_PRIO); + return semdef; +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_delete(osal_semaphore_t semd_hdl) { + return RT_EOK == rt_sem_detach(semd_hdl); } TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { - (void) in_isr; - return rt_sem_release(sem_hdl) == RT_EOK; + (void) in_isr; + return rt_sem_release(sem_hdl) == RT_EOK; } TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) { - return rt_sem_take(sem_hdl, rt_tick_from_millisecond((rt_int32_t) msec)) == RT_EOK; + return rt_sem_take(sem_hdl, rt_tick_from_millisecond((rt_int32_t) msec)) == RT_EOK; } TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) { - rt_sem_control(sem_hdl, RT_IPC_CMD_RESET, 0); + rt_sem_control(sem_hdl, RT_IPC_CMD_RESET, 0); } //--------------------------------------------------------------------+ @@ -74,16 +78,20 @@ typedef struct rt_mutex osal_mutex_def_t; typedef rt_mutex_t osal_mutex_t; TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t *mdef) { - rt_mutex_init(mdef, "tusb", RT_IPC_FLAG_PRIO); - return mdef; + rt_mutex_init(mdef, "tusb", RT_IPC_FLAG_PRIO); + return mdef; +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_delete(osal_mutex_t mutex_hdl) { + return RT_EOK == rt_mutex_detach(mutex_hdl); } TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) { - return rt_mutex_take(mutex_hdl, rt_tick_from_millisecond((rt_int32_t) msec)) == RT_EOK; + return rt_mutex_take(mutex_hdl, rt_tick_from_millisecond((rt_int32_t) msec)) == RT_EOK; } TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) { - return rt_mutex_release(mutex_hdl) == RT_EOK; + return rt_mutex_release(mutex_hdl) == RT_EOK; } //--------------------------------------------------------------------+ @@ -106,27 +114,31 @@ typedef struct { typedef rt_mq_t osal_queue_t; TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t *qdef) { - rt_mq_init(&(qdef->sq), "tusb", qdef->buf, qdef->item_sz, - qdef->item_sz * qdef->depth, RT_IPC_FLAG_PRIO); - return &(qdef->sq); + rt_mq_init(&(qdef->sq), "tusb", qdef->buf, qdef->item_sz, + qdef->item_sz * qdef->depth, RT_IPC_FLAG_PRIO); + return &(qdef->sq); +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_delete(osal_queue_t qhdl) { + return RT_EOK == rt_mq_detach(qhdl); } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void *data, uint32_t msec) { - rt_tick_t tick = rt_tick_from_millisecond((rt_int32_t) msec); + rt_tick_t tick = rt_tick_from_millisecond((rt_int32_t) msec); #if RT_VERSION_MAJOR >= 5 - return rt_mq_recv(qhdl, data, qhdl->msg_size, tick) > 0; + return rt_mq_recv(qhdl, data, qhdl->msg_size, tick) > 0; #else - return rt_mq_recv(qhdl, data, qhdl->msg_size, tick) == RT_EOK; + return rt_mq_recv(qhdl, data, qhdl->msg_size, tick) == RT_EOK; #endif /* RT_VERSION_MAJOR >= 5 */ } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const *data, bool in_isr) { - (void) in_isr; - return rt_mq_send(qhdl, (void *)data, qhdl->msg_size) == RT_EOK; + (void) in_isr; + return rt_mq_send(qhdl, (void *)data, qhdl->msg_size) == RT_EOK; } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) { - return (qhdl->entry) == 0; + return (qhdl->entry) == 0; } #ifdef __cplusplus From 0610070d07babf3623016603325afa938d4fc9f7 Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Mon, 25 Mar 2024 18:44:51 +0700 Subject: [PATCH 164/454] Update dcd_stm32_fsdev_pvt_st.h --- .../st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h index e0df21860..5a129ecf8 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h @@ -296,17 +296,14 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_cnt(USB_TypeDef * USB { #ifdef FSDEV_BUS_32BIT (void) USBx; - volatile uint32_t count = 10; - /* - WA: few cycles for RX PMA descriptor to update - This workaround is ported from stm32h5xx_hal_pcd.h : PCD_GET_EP_RX_CNT H5 - This code fixes an issue when the code is compiled in GCC with a fast optimization(O2/O3) and device with an high frequency. - The function doesn't return the correct value. - Issue observed on Windows 10 and stm32h573i_dk and tud_task() scheduled by IT, the device is not migrated the USB device is not visible . + /* WA: few cycles for RX PMA descriptor to update, otherwise doesn't return the correct value. + Note: required for G0, U5, H5 etc. + This workaround is ported from stm32h5xx_hal_pcd.h and fixes the issue when calling this function fast enough. + Reproduced with GCC ast optimization(O2/O3) and stm32h573i_dk with an high frequency. + Observed on Windows 10 where tud_task() is scheduled by interrupt handler. */ - while (count > 0U) - { - asm("NOP"); + volatile uint32_t count = 10; // defined as PCD_RX_PMA_CNT in stm32 hal_driver + while (count > 0U) { count--; } return (pma32[2*bEpIdx + 1] & 0x03FF0000) >> 16; From 29f016ae15eb94654748bf29b81557f6ab611384 Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Mon, 25 Mar 2024 18:59:05 +0700 Subject: [PATCH 165/454] fix pre-commit --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h index 5a129ecf8..ade64b4fb 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h @@ -297,9 +297,9 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_cnt(USB_TypeDef * USB #ifdef FSDEV_BUS_32BIT (void) USBx; /* WA: few cycles for RX PMA descriptor to update, otherwise doesn't return the correct value. - Note: required for G0, U5, H5 etc. + Note: required for G0, U5, H5 etc. This workaround is ported from stm32h5xx_hal_pcd.h and fixes the issue when calling this function fast enough. - Reproduced with GCC ast optimization(O2/O3) and stm32h573i_dk with an high frequency. + Reproduced with GCC ast optimization(O2/O3) and stm32h573i_dk with an high frequency. Observed on Windows 10 where tud_task() is scheduled by interrupt handler. */ volatile uint32_t count = 10; // defined as PCD_RX_PMA_CNT in stm32 hal_driver From 8f04d96c07aff30cecb608fa61d54a6e6f5b99ef Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Mon, 25 Mar 2024 22:53:24 +0900 Subject: [PATCH 166/454] Add small RAM MCUs/boards to skip list --- examples/device/video_capture_2ch/skip.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/examples/device/video_capture_2ch/skip.txt b/examples/device/video_capture_2ch/skip.txt index db64cc639..b36abf721 100644 --- a/examples/device/video_capture_2ch/skip.txt +++ b/examples/device/video_capture_2ch/skip.txt @@ -1,4 +1,13 @@ mcu:MSP430x5xx mcu:NUC121 mcu:SAMD11 +mcu:GD32VF103 +mcu:CH32V307 family:espressif +board:curiosity_nano +board:kuiic +board:frdm_k32l2b +board:lpcxpresso11u68 +board:stm32f303disco +board:stm32l412nucleo +board:ek_tm4c123gxl From 6a14dd190fa21d0632c956040fc0b2c0f41c676f Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Mon, 25 Mar 2024 23:24:24 +0900 Subject: [PATCH 167/454] Fix compile errors when High Speed --- examples/device/video_capture_2ch/src/usb_descriptors.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/device/video_capture_2ch/src/usb_descriptors.c b/examples/device/video_capture_2ch/src/usb_descriptors.c index 0c1066416..e5798f7f2 100644 --- a/examples/device/video_capture_2ch/src/usb_descriptors.c +++ b/examples/device/video_capture_2ch/src/usb_descriptors.c @@ -558,7 +558,8 @@ static uint8_t * get_hs_configuration_desc(void) { desc_hs_configuration = desc_fs_configuration; // change endpoint bulk size to 512 if bulk streaming if (CFG_TUD_VIDEO_STREAMING_BULK) { - desc_hs_configuration.video_streaming.ep.wMaxPacketSize = 512; + desc_hs_configuration.uvc[0].video_streaming.ep.wMaxPacketSize = 512; + desc_hs_configuration.uvc[1].video_streaming.ep.wMaxPacketSize = 512; } } init = true; From fbb20373c1b22c8eb1aed4fa95972c851be819f3 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 26 Mar 2024 10:26:42 +0700 Subject: [PATCH 168/454] implement hcd_deinit() for max3421 --- src/portable/analog/max3421/hcd_max3421.c | 35 +++++++++++++++++------ 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index cc4799dd6..d70cf7208 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -321,35 +321,35 @@ static void fifo_read(uint8_t rhport, uint8_t * buffer, uint16_t len, bool in_is } //------------- register write helper -------------// -static inline void hirq_write(uint8_t rhport, uint8_t data, bool in_isr) { +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 _hcd_data.hirq &= (uint8_t) ~data; } -static inline void hien_write(uint8_t rhport, uint8_t data, bool in_isr) { +TU_ATTR_ALWAYS_INLINE static inline void hien_write(uint8_t rhport, uint8_t data, bool in_isr) { _hcd_data.hien = data; reg_write(rhport, HIEN_ADDR, data, in_isr); } -static inline void mode_write(uint8_t rhport, uint8_t data, bool in_isr) { +TU_ATTR_ALWAYS_INLINE static inline void mode_write(uint8_t rhport, uint8_t data, bool in_isr) { _hcd_data.mode = data; reg_write(rhport, MODE_ADDR, data, in_isr); } -static inline void peraddr_write(uint8_t rhport, uint8_t data, bool in_isr) { +TU_ATTR_ALWAYS_INLINE static inline void peraddr_write(uint8_t rhport, uint8_t data, bool in_isr) { if ( _hcd_data.peraddr == data ) return; // no need to change address _hcd_data.peraddr = data; reg_write(rhport, PERADDR_ADDR, data, in_isr); } -static inline void hxfr_write(uint8_t rhport, uint8_t data, bool in_isr) { +TU_ATTR_ALWAYS_INLINE static inline void hxfr_write(uint8_t rhport, uint8_t data, bool in_isr) { _hcd_data.hxfr = data; reg_write(rhport, HXFR_ADDR, data, in_isr); } -static inline void sndbc_write(uint8_t rhport, uint8_t data, bool in_isr) { +TU_ATTR_ALWAYS_INLINE static inline void sndbc_write(uint8_t rhport, uint8_t data, bool in_isr) { _hcd_data.sndbc = data; reg_write(rhport, SNDBC_ADDR, data, in_isr); } @@ -449,7 +449,7 @@ bool hcd_init(uint8_t rhport) { // full duplex, interrupt negative edge reg_write(rhport, PINCTL_ADDR, PINCTL_FDUPSPI, false); - // V1 is 0x01, V2 is 0x12, V3 is 0x13 + // 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); @@ -481,6 +481,24 @@ bool hcd_init(uint8_t rhport) { return true; } +bool hcd_deinit(uint8_t rhport) { + (void) rhport; + + // disable interrupt + tuh_max3421_int_api(rhport, false); + + // reset max3421 + reg_write(rhport, USBCTL_ADDR, USBCTL_CHIPRES, false); + reg_write(rhport, USBCTL_ADDR, 0, false); + + #if OSAL_MUTEX_REQUIRED + osal_mutex_delete(_hcd_data.spi_mutex); + _hcd_data.spi_mutex = NULL; + #endif + + return true; +} + // Enable USB interrupt // Not actually enable GPIO interrupt, just set variable to prevent handler to process void hcd_int_enable (uint8_t rhport) { @@ -598,7 +616,8 @@ void xact_in(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_isr) { hxfr_write(rhport, hxfr, in_isr); } -TU_ATTR_ALWAYS_INLINE static inline void xact_inout(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_isr) { +TU_ATTR_ALWAYS_INLINE static inline +void xact_inout(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_isr) { if (ep->ep_num == 0 ) { // setup if (ep->is_setup) { From 64bc0aac551d13cf781a2b41b6239b0716f61049 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 26 Mar 2024 10:39:51 +0700 Subject: [PATCH 169/454] update doc index.rst to match readme.rst (duplicated) --- docs/reference/index.rst | 47 ++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/docs/reference/index.rst b/docs/reference/index.rst index a9663ee7d..9ecdf619b 100644 --- a/docs/reference/index.rst +++ b/docs/reference/index.rst @@ -4,44 +4,69 @@ Reference .. figure:: ../assets/stack.svg :width: 1600px - :alt: stackup + :alt: TinyUSB + +:: + + . + ├── docs # Documentation + ├── examples # Examples with make and cmake build system + ├── hw + │ ├── bsp # Supported boards source files + │ └── mcu # Low level mcu core & peripheral drivers + ├── lib # Sources from 3rd party such as freeRTOS, fatfs ... + ├── src # All sources files for TinyUSB stack itself. + ├── test # Tests: unit test, fuzzing, hardware test + └── tools # Files used internally - representation of the TinyUSB stack. Device Stack ============ -Supports multiple device configurations by dynamically changing usb descriptors. Low power functions such like suspend, resume, and remote wakeup. Following device classes are supported: +Supports multiple device configurations by dynamically changing USB descriptors, low power functions such like suspend, resume, and remote wakeup. The following device classes are supported: - Audio Class 2.0 (UAC2) - Bluetooth Host Controller Interface (BTH HCI) -- Communication Class (CDC) -- Device Firmware Update (DFU): DFU mode (WIP) and Runtinme +- Communication Device Class (CDC) +- Device Firmware Update (DFU): DFU mode (WIP) and Runtime - Human Interface Device (HID): Generic (In & Out), Keyboard, Mouse, Gamepad etc ... - Mass Storage Class (MSC): with multiple LUNs - Musical Instrument Digital Interface (MIDI) -- Network with RNDIS, CDC-ECM (work in progress) -- USB Test and Measurement Class (USBTMC) +- Network with RNDIS, Ethernet Control Model (ECM), Network Control Model (NCM) +- Test and Measurement Class (USBTMC) +- Video class 1.5 (UVC): work in progress - Vendor-specific class support with generic In & Out endpoints. Can be used with MS OS 2.0 compatible descriptor to load winUSB driver without INF file. - `WebUSB `__ with vendor-specific class -If you have special need, `usbd_app_driver_get_cb()` can be used to write your own class driver without modifying the stack. Here is how RPi team add their reset interface `raspberrypi/pico-sdk#197 `__ +If you have a special requirement, `usbd_app_driver_get_cb()` can be used to write your own class driver without modifying the stack. Here is how the RPi team added their reset interface `raspberrypi/pico-sdk#197 `_ Host Stack ========== - Human Interface Device (HID): Keyboard, Mouse, Generic - Mass Storage Class (MSC) -- Hub currently only supports 1 level of hub (due to my laziness) +- Communication Device Class: CDC-ACM +- Vendor serial over USB: FTDI, CP210x +- 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. + +TypeC PD Stack +============== + +- Power Delivery 3.0 (PD3.0) with USB Type-C support (WIP) +- Super early stage, only for testing purpose +- Only support STM32 G4 OS Abstraction layer ==================== -TinyUSB is completely thread-safe by pushing all ISR events into a central queue, then process it later in the non-ISR context task function. It also uses semaphore/mutex to access shared resources such as CDC FIFO. Therefore the stack needs to use some of OS's basic APIs. Following OSes are already supported out of the box. +TinyUSB is completely thread-safe by pushing all Interrupt Service Request (ISR) events into a central queue, then processing them later in the non-ISR context task function. It also uses semaphore/mutex to access shared resources such as Communication Device Class (CDC) FIFO. Therefore the stack needs to use some of the OS's basic APIs. Following OSes are already supported out of the box. - **No OS** - **FreeRTOS** -- **Mynewt** Due to the newt package build system, Mynewt examples are better to be on its `own repo `__ +- `RT-Thread `_: `repo `_ +- **Mynewt** Due to the newt package build system, Mynewt examples are better to be on its `own repo `_ License ======= From 9fdb1c1684c653426d4f616d788b329ee528110a Mon Sep 17 00:00:00 2001 From: IngHK Date: Tue, 26 Mar 2024 08:10:32 +0100 Subject: [PATCH 170/454] draft MAX3421E NAK retry handling next frame --- src/portable/analog/max3421/hcd_max3421.c | 45 ++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index d70cf7208..d366298ea 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -28,6 +28,8 @@ #if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 +#define NAK_RETRY_HANDLING 1 + #include #include "host/hcd.h" @@ -180,6 +182,9 @@ typedef struct { uint8_t data_toggle : 1; uint8_t xfer_pending : 1; uint8_t xfer_complete : 1; +#if NAK_RETRY_HANDLING + uint8_t retry_pending : 1; +#endif }; struct TU_ATTR_PACKED { @@ -593,7 +598,7 @@ void xact_out(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool 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,); +// TU_ASSERT(_hcd_data.hirq & HIRQ_SNDBAV_IRQ,); if (xact_len) { fifo_write(rhport, SNDFIFO_ADDR, ep->buf, xact_len, in_isr); } @@ -803,6 +808,7 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) { xfer_result_t xfer_result; switch(hresult) { case HRSL_SUCCESS: +// putchar('S'); xfer_result = XFER_RESULT_SUCCESS; break; @@ -811,6 +817,19 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) { break; case HRSL_NAK: +// putchar('N'); +#if NAK_RETRY_HANDLING + ep->retry_pending = 1; + ep->xfer_pending = 0; + max3421_ep_t * next_ep = find_next_pending_ep(ep); + if (next_ep) { + // switch to next pending TODO could have issue with double buffered if not clear previously out data + xact_inout(rhport, next_ep, true, in_isr); + } else { + // no more pending + atomic_flag_clear(&_hcd_data.busy); + } +#else if (ep_num == 0) { // NAK on control, retry immediately hxfr_write(rhport, _hcd_data.hxfr, in_isr); @@ -828,6 +847,7 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) { TU_ASSERT(false,); } } +#endif return; case HRSL_BAD_REQ: @@ -909,6 +929,29 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { if (hirq & HIRQ_FRAME_IRQ) { _hcd_data.frame_count++; + +#if NAK_RETRY_HANDLING + // retry EPs + max3421_ep_t * next_ep = NULL; + for (size_t i = 0; i < CFG_TUH_MAX3421_ENDPOINT_TOTAL; i++) { + max3421_ep_t * ep = &_hcd_data.ep[i]; + // set retryable EPs to pending + if (ep->retry_pending) { +// putchar('R'); + ep->xfer_pending = 1; + ep->retry_pending = 0; + if (next_ep == NULL) { + next_ep = &_hcd_data.ep[i]; + } + } + } + // trigger 1st retryable EP + if (next_ep) { + if ( !atomic_flag_test_and_set(&_hcd_data.busy) ) { + xact_inout(rhport, next_ep, true, in_isr); + } + } +#endif } if (hirq & HIRQ_CONDET_IRQ) { From ecea890fdc7a0dc4b92a365f0455b7b91258d543 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 26 Mar 2024 16:56:13 +0700 Subject: [PATCH 171/454] use usbreset to reset built-in usb 2.0 hub VIA Labs before each test --- .github/workflows/build_esp.yml | 16 +++++++++++----- .github/workflows/cmake_arm.yml | 16 +++++++++++----- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build_esp.yml b/.github/workflows/build_esp.yml index 07cbf3552..b44da51e6 100644 --- a/.github/workflows/build_esp.yml +++ b/.github/workflows/build_esp.yml @@ -86,11 +86,17 @@ jobs: # USB bus on rpi4 is not stable, reset it before testing - name: Reset USB bus run: | - 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 + lsusb + lsusb -t + # reset VIA Labs 2.0 hub + 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 diff --git a/.github/workflows/cmake_arm.yml b/.github/workflows/cmake_arm.yml index 732e9b9df..c44d3780e 100644 --- a/.github/workflows/cmake_arm.yml +++ b/.github/workflows/cmake_arm.yml @@ -141,11 +141,17 @@ jobs: # USB bus on rpi4 is not stable, reset it before testing - name: Reset USB bus run: | - 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 + lsusb + lsusb -t + # reset VIA Labs 2.0 hub + 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 From 7f1e327be3feca54cef56a3fadf49465fa452c06 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 26 Mar 2024 17:13:02 +0700 Subject: [PATCH 172/454] add sudo usbreset --- .github/workflows/build_esp.yml | 2 +- .github/workflows/cmake_arm.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_esp.yml b/.github/workflows/build_esp.yml index b44da51e6..d283c6535 100644 --- a/.github/workflows/build_esp.yml +++ b/.github/workflows/build_esp.yml @@ -89,7 +89,7 @@ jobs: lsusb lsusb -t # reset VIA Labs 2.0 hub - usbreset 001/002 + sudo usbreset 001/002 # legacy code #for port in $(lspci | grep USB | cut -d' ' -f1); do diff --git a/.github/workflows/cmake_arm.yml b/.github/workflows/cmake_arm.yml index c44d3780e..1e5f61e0e 100644 --- a/.github/workflows/cmake_arm.yml +++ b/.github/workflows/cmake_arm.yml @@ -144,7 +144,7 @@ jobs: lsusb lsusb -t # reset VIA Labs 2.0 hub - usbreset 001/002 + sudo usbreset 001/002 # legacy code #for port in $(lspci | grep USB | cut -d' ' -f1); do From 307cce92c4f630ab988e6eb1e77685bc1e82d85a Mon Sep 17 00:00:00 2001 From: Camila Date: Tue, 26 Mar 2024 18:40:22 +0100 Subject: [PATCH 173/454] Improved SDK 3.2.0 compatibility - Used usbdev_allocreq for compatibility with SDK 3.2.0 - Wrapped previous code in #ifdef for legacy compatibility --- src/portable/sony/cxd56/dcd_cxd56.c | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/src/portable/sony/cxd56/dcd_cxd56.c b/src/portable/sony/cxd56/dcd_cxd56.c index 9a939bc6c..83cd0718c 100644 --- a/src/portable/sony/cxd56/dcd_cxd56.c +++ b/src/portable/sony/cxd56/dcd_cxd56.c @@ -39,25 +39,6 @@ #define CXD56_SETUP_QUEUE_DEPTH (4) #define CXD56_MAX_DATA_OUT_SIZE (64) -/* Allocate/free I/O requests. - * Should not be called from interrupt processing! - */ - -#define EP_ALLOCREQ(ep) (ep)->ops->allocreq(ep) -#define EP_FREEREQ(ep,req) (ep)->ops->freereq(ep,req) - -/* Allocate/free an I/O buffer. - * Should not be called from interrupt processing! - */ - -#ifdef CONFIG_USBDEV_DMA -# define EP_ALLOCBUFFER(ep,nb) (ep)->ops->allocbuffer(ep,nb) -# define EP_FREEBUFFER(ep,buf) (ep)->ops->freebuffer(ep,buf) -#else -# define EP_ALLOCBUFFER(ep,nb) kmm_malloc(nb) -# define EP_FREEBUFFER(ep,buf) kmm_free(buf) -#endif - OSAL_QUEUE_DEF(usbd_int_set, _setup_queue_def, CXD56_SETUP_QUEUE_DEPTH, struct usb_ctrlreq_s); struct usbdcd_driver_s @@ -121,6 +102,7 @@ static int _dcd_bind(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_ usbdev = dev; usbdcd_driver.ep[0] = dev->ep0; + #ifdef EP_ALLOCREQ usbdcd_driver.req[0] = EP_ALLOCREQ(usbdcd_driver.ep[0]); if (usbdcd_driver.req[0] != NULL) { @@ -132,6 +114,9 @@ static int _dcd_bind(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_ usbdcd_driver.req[0] = NULL; } } + #else + usbdcd_driver.req[0] = usbdev_allocreq(usbdcd_driver.ep[0],64); + #endif usbdcd_driver.req[0]->callback = usbdcd_ep0incomplete; @@ -314,12 +299,18 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *p_endpoint_desc) } usbdcd_driver.req[epnum] = NULL; + + #ifdef EP_ALLOCREQ usbdcd_driver.req[epnum] = EP_ALLOCREQ(usbdcd_driver.ep[epnum]); if (usbdcd_driver.req[epnum] != NULL) { usbdcd_driver.req[epnum]->len = ep_mps; } else + #else + usbdcd_driver.req[epnum] = usbdev_allocreq(usbdcd_driver.ep[epnum], ep_mps); + if(usbdcd_driver.req[epnum] == NULL) + #endif { return false; } From 62864d53560baa0b23a1bbc4ea82faf403ac01dc Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Thu, 28 Mar 2024 12:12:07 +0700 Subject: [PATCH 174/454] Update labeler.yml --- .github/workflows/labeler.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index b4a2cdafa..4733c6f06 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -14,7 +14,7 @@ jobs: - name: Label New Issue or PR uses: actions/github-script@v7 with: - github-token: ${{ secrets.API_TOKEN_GITHUB }} + github-token: ${{ secrets.GITHUB_TOKEN }} script: | let label = ''; let username = ''; From 275e2f318ec17ba3956eb89965831ad5dff402be Mon Sep 17 00:00:00 2001 From: duckylotl <163729266+duckylotl@users.noreply.github.com> Date: Thu, 28 Mar 2024 10:27:07 +0100 Subject: [PATCH 175/454] forward declare board_millis for OPT_OS_CUSTOM --- hw/bsp/board_api.h | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/bsp/board_api.h b/hw/bsp/board_api.h index 0c8a35924..3b9f211a2 100644 --- a/hw/bsp/board_api.h +++ b/hw/bsp/board_api.h @@ -116,6 +116,7 @@ static inline uint32_t board_millis(void) { #elif CFG_TUSB_OS == OPT_OS_CUSTOM // Implement your own board_millis() in any of .c file +uint32_t board_millis(void); #else #error "board_millis() is not implemented for this OS" From 0da1da942a735bcac7b48786a511a38b02519e88 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 28 Mar 2024 16:32:02 +0700 Subject: [PATCH 176/454] enhance hub removal using while loop to unroll recursive instead of event queue. --- src/host/usbh.c | 117 +++++++++++++++++++++++------------------------- 1 file changed, 57 insertions(+), 60 deletions(-) diff --git a/src/host/usbh.c b/src/host/usbh.c index 1edc43fd6..71691fad6 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -1138,43 +1138,42 @@ bool tuh_interface_set(uint8_t daddr, uint8_t itf_num, uint8_t itf_alt, TU_VERIFY(_async_func(__VA_ARGS__, NULL, (uintptr_t) &result), XFER_RESULT_TIMEOUT); \ return (uint8_t) result -uint8_t tuh_descriptor_get_sync(uint8_t daddr, uint8_t type, uint8_t index, void* buffer, uint16_t len) -{ +uint8_t tuh_descriptor_get_sync(uint8_t daddr, uint8_t type, uint8_t index, + void* buffer, uint16_t len) { _CONTROL_SYNC_API(tuh_descriptor_get, daddr, type, index, buffer, len); } -uint8_t tuh_descriptor_get_device_sync(uint8_t daddr, void* buffer, uint16_t len) -{ +uint8_t tuh_descriptor_get_device_sync(uint8_t daddr, void* buffer, uint16_t len) { _CONTROL_SYNC_API(tuh_descriptor_get_device, daddr, buffer, len); } -uint8_t tuh_descriptor_get_configuration_sync(uint8_t daddr, uint8_t index, void* buffer, uint16_t len) -{ +uint8_t tuh_descriptor_get_configuration_sync(uint8_t daddr, uint8_t index, + void* buffer, uint16_t len) { _CONTROL_SYNC_API(tuh_descriptor_get_configuration, daddr, index, buffer, len); } -uint8_t tuh_descriptor_get_hid_report_sync(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, uint8_t index, void* buffer, uint16_t len) -{ +uint8_t tuh_descriptor_get_hid_report_sync(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, uint8_t index, + void* buffer, uint16_t len) { _CONTROL_SYNC_API(tuh_descriptor_get_hid_report, daddr, itf_num, desc_type, index, buffer, len); } -uint8_t tuh_descriptor_get_string_sync(uint8_t daddr, uint8_t index, uint16_t language_id, void* buffer, uint16_t len) -{ +uint8_t tuh_descriptor_get_string_sync(uint8_t daddr, uint8_t index, uint16_t language_id, + void* buffer, uint16_t len) { _CONTROL_SYNC_API(tuh_descriptor_get_string, daddr, index, language_id, buffer, len); } -uint8_t tuh_descriptor_get_manufacturer_string_sync(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len) -{ +uint8_t tuh_descriptor_get_manufacturer_string_sync(uint8_t daddr, uint16_t language_id, + void* buffer, uint16_t len) { _CONTROL_SYNC_API(tuh_descriptor_get_manufacturer_string, daddr, language_id, buffer, len); } -uint8_t tuh_descriptor_get_product_string_sync(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len) -{ +uint8_t tuh_descriptor_get_product_string_sync(uint8_t daddr, uint16_t language_id, + void* buffer, uint16_t len) { _CONTROL_SYNC_API(tuh_descriptor_get_product_string, daddr, language_id, buffer, len); } -uint8_t tuh_descriptor_get_serial_string_sync(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len) -{ +uint8_t tuh_descriptor_get_serial_string_sync(uint8_t daddr, uint16_t language_id, + void* buffer, uint16_t len) { _CONTROL_SYNC_API(tuh_descriptor_get_serial_string, daddr, language_id, buffer, len); } @@ -1210,57 +1209,55 @@ TU_ATTR_ALWAYS_INLINE static inline bool is_hub_addr(uint8_t daddr) { static void process_removing_device(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port) { //------------- find the all devices (star-network) under port that is unplugged -------------// // TODO mark as disconnected in ISR, also handle dev0 + uint32_t removing_hubs = 0; + do { + for (uint8_t dev_id = 0; dev_id < TOTAL_DEVICES; dev_id++) { + usbh_device_t* dev = &_usbh_devices[dev_id]; + uint8_t const daddr = dev_id + 1; -#if 0 - // index as hub addr, value is hub port (0xFF for invalid) - uint8_t removing_hubs[CFG_TUH_HUB]; - memset(removing_hubs, TUSB_INDEX_INVALID_8, sizeof(removing_hubs)); + // hub_addr = 0 means roothub, hub_port = 0 means all devices of downstream hub + if (dev->rhport == rhport && dev->connected && + (hub_addr == 0 || dev->hub_addr == hub_addr) && + (hub_port == 0 || dev->hub_port == hub_port)) { + TU_LOG_USBH("Device unplugged address = %u\r\n", daddr); - removing_hubs[hub_addr-CFG_TUH_DEVICE_MAX] = hub_port; + if (is_hub_addr(daddr)) { + TU_LOG_USBH(" is a HUB device %u\r\n", daddr); + // marking this hub to run the loop on its children next (unroll recursive) + removing_hubs |= TU_BIT(dev_id - CFG_TUH_DEVICE_MAX); + } else { + // Invoke callback before closing driver (maybe call it later ?) + if (tuh_umount_cb) tuh_umount_cb(daddr); + } - // consecutive non-removing hub - uint8_t nop_count = 0; -#endif + // Close class driver + for (uint8_t drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) { + usbh_class_driver_t const* driver = get_driver(drv_id); + if (driver) driver->close(daddr); + } - for (uint8_t dev_id = 0; dev_id < TOTAL_DEVICES; dev_id++) { - usbh_device_t *dev = &_usbh_devices[dev_id]; - uint8_t const daddr = dev_id + 1; + hcd_device_close(rhport, daddr); + clear_device(dev); - // hub_addr = 0 means roothub, hub_port = 0 means all devices of downstream hub - if (dev->rhport == rhport && dev->connected && - (hub_addr == 0 || dev->hub_addr == hub_addr) && - (hub_port == 0 || dev->hub_port == hub_port)) { - TU_LOG_USBH("Device unplugged address = %u\r\n", daddr); - - if (is_hub_addr(daddr)) { - TU_LOG_USBH(" is a HUB device %u\r\n", daddr); - - // Submit removed event If the device itself is a hub (un-rolled recursive) - // TODO a better to unroll recursrive is using array of removing_hubs and mark it here - hcd_event_t event; - event.rhport = rhport; - event.event_id = HCD_EVENT_DEVICE_REMOVE; - event.connection.hub_addr = daddr; - event.connection.hub_port = 0; - - hcd_event_handler(&event, false); - } else { - // Invoke callback before closing driver (maybe call it later ?) - if (tuh_umount_cb) tuh_umount_cb(daddr); + // abort on-going control xfer on this device if any + if (_ctrl_xfer.daddr == daddr) _set_control_xfer_stage(CONTROL_STAGE_IDLE); } - - // Close class driver - for (uint8_t drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) { - usbh_class_driver_t const * driver = get_driver(drv_id); - if ( driver ) driver->close(daddr); - } - - hcd_device_close(rhport, daddr); - clear_device(dev); - // abort on-going control xfer if any - if (_ctrl_xfer.daddr == daddr) _set_control_xfer_stage(CONTROL_STAGE_IDLE); } - } + + if (removing_hubs == 0) break; + + // find the next hub to process + for (uint8_t h_id = 0; h_id < CFG_TUH_HUB; h_id++) { + if (tu_bit_test(removing_hubs, h_id)) { + removing_hubs &= ~TU_BIT(h_id); + + // update hub_addr and hub_port for next loop + hub_addr = h_id + 1 + CFG_TUH_DEVICE_MAX; + hub_port = 0; + break; + } + } + } while(1); } //--------------------------------------------------------------------+ From 3dcb7362aa8f0e710157da4b28be44abb2c26230 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 28 Mar 2024 19:18:20 +0700 Subject: [PATCH 177/454] fix build when CFG_TUH_HUB == 0 --- src/host/usbh.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/host/usbh.c b/src/host/usbh.c index 71691fad6..f2dc2f7c1 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -1219,11 +1219,10 @@ static void process_removing_device(uint8_t rhport, uint8_t hub_addr, uint8_t hu if (dev->rhport == rhport && dev->connected && (hub_addr == 0 || dev->hub_addr == hub_addr) && (hub_port == 0 || dev->hub_port == hub_port)) { - TU_LOG_USBH("Device unplugged address = %u\r\n", daddr); + TU_LOG_USBH("[%u:%u:%u] unplugged address = %u\r\n", rhport, hub_addr, hub_port, daddr); if (is_hub_addr(daddr)) { TU_LOG_USBH(" is a HUB device %u\r\n", daddr); - // marking this hub to run the loop on its children next (unroll recursive) removing_hubs |= TU_BIT(dev_id - CFG_TUH_DEVICE_MAX); } else { // Invoke callback before closing driver (maybe call it later ?) @@ -1244,9 +1243,11 @@ static void process_removing_device(uint8_t rhport, uint8_t hub_addr, uint8_t hu } } + // if removing a hub, we need to remove its downstream devices + #if CFG_TUH_HUB if (removing_hubs == 0) break; - // find the next hub to process + // find a marked hub to process for (uint8_t h_id = 0; h_id < CFG_TUH_HUB; h_id++) { if (tu_bit_test(removing_hubs, h_id)) { removing_hubs &= ~TU_BIT(h_id); @@ -1257,6 +1258,10 @@ static void process_removing_device(uint8_t rhport, uint8_t hub_addr, uint8_t hu break; } } + #else + (void) removing_hubs; + break; + #endif } while(1); } From d50003e33d89740c0993ae236629392df82453c2 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 27 Mar 2024 11:21:13 -0700 Subject: [PATCH 178/454] Fake unplug devices when a root hub is deinit --- src/host/usbh.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/host/usbh.c b/src/host/usbh.c index f2dc2f7c1..29c6eb1e9 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -415,6 +415,15 @@ bool tuh_deinit(uint8_t rhport) { _usbh_controller = TUSB_INDEX_INVALID_8; + // "unplug" all devices on this rhport + for (uint8_t idx = 0; idx < CFG_TUH_DEVICE_MAX + CFG_TUH_HUB; idx++) { + usbh_device_t *dev = &_usbh_devices[idx]; + if (!dev->connected || dev->rhport != rhport) { + continue; + } + process_removing_device(rhport, dev->hub_addr, dev->hub_port); + } + // deinit host stack if no controller is active if (!tuh_inited()) { // Class drivers From ddb1034a9c77d8ef4efccf3df76013f86efe5e09 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 28 Mar 2024 21:45:52 +0700 Subject: [PATCH 179/454] use hub_addr=0, hub_port=0 for removing root hub port --- src/host/usbh.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/host/usbh.c b/src/host/usbh.c index 29c6eb1e9..05091736e 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -412,17 +412,10 @@ bool tuh_deinit(uint8_t rhport) { // deinit host controller hcd_int_disable(rhport); hcd_deinit(rhport); - _usbh_controller = TUSB_INDEX_INVALID_8; - // "unplug" all devices on this rhport - for (uint8_t idx = 0; idx < CFG_TUH_DEVICE_MAX + CFG_TUH_HUB; idx++) { - usbh_device_t *dev = &_usbh_devices[idx]; - if (!dev->connected || dev->rhport != rhport) { - continue; - } - process_removing_device(rhport, dev->hub_addr, dev->hub_port); - } + // "unplug" all devices on this rhport (hub_addr = 0, hub_port = 0) + process_removing_device(rhport, 0, 0); // deinit host stack if no controller is active if (!tuh_inited()) { From b9400df4c8bd49f1dd1e3047ca2a2c0284fa785e Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 29 Mar 2024 11:23:36 +0700 Subject: [PATCH 180/454] fix rp2 debug build with level 3 --- src/portable/raspberrypi/rp2040/hcd_rp2040.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index 08aef9314..b351a9a07 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -113,7 +113,7 @@ static void __tusb_irq_path_func(_handle_buff_status_bit)(uint bit, struct hw_en static void __tusb_irq_path_func(hw_handle_buff_status)(void) { uint32_t remaining_buffers = usb_hw->buf_status; - pico_trace("buf_status 0x%08x\n", remaining_buffers); + pico_trace("buf_status 0x%08lx\n", remaining_buffers); // Check EPX first uint bit = 0b1; @@ -325,10 +325,8 @@ static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t ep->wMaxPacketSize = wMaxPacketSize; ep->transfer_type = transfer_type; - pico_trace("hw_endpoint_init dev %d ep %d %s xfer %d\n", ep->dev_addr, tu_edpt_number(ep->ep_addr), - ep_dir_string[tu_edpt_dir(ep->ep_addr)], ep->transfer_type); - pico_trace("dev %d ep %d %s setup buffer @ 0x%p\n", ep->dev_addr, tu_edpt_number(ep->ep_addr), - ep_dir_string[tu_edpt_dir(ep->ep_addr)], ep->hw_data_buf); + pico_trace("hw_endpoint_init dev %d ep %02X xfer %d\n", ep->dev_addr, ep->ep_addr, ep->transfer_type); + pico_trace("dev %d ep %02X setup buffer @ 0x%p\n", ep->dev_addr, ep->ep_addr, ep->hw_data_buf); uint dpram_offset = hw_data_offset(ep->hw_data_buf); // Bits 0-5 should be 0 assert(!(dpram_offset & 0b111111)); @@ -343,7 +341,7 @@ static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t ep_reg |= (uint32_t) ((bmInterval - 1) << EP_CTRL_HOST_INTERRUPT_INTERVAL_LSB); } *ep->endpoint_control = ep_reg; - pico_trace("endpoint control (0x%p) <- 0x%x\n", ep->endpoint_control, ep_reg); + pico_trace("endpoint control (0x%p) <- 0x%lx\n", ep->endpoint_control, ep_reg); ep->configured = true; if ( ep != &epx ) From cab11064160deab42af654cd766bbfaca7f688cd Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Tue, 21 Nov 2023 18:06:57 +0100 Subject: [PATCH 181/454] dwc2: add endpoint allocation support. --- src/class/audio/audio_device.c | 4 +- src/portable/synopsys/dwc2/dcd_dwc2.c | 102 ++++++++++++++++++++++++++ 2 files changed, 104 insertions(+), 2 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 4adc558a6..293defd96 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -96,8 +96,8 @@ #define USE_LINEAR_BUFFER 1 #endif -// Temporarily put the check here for stm32_fsdev -#ifdef TUP_USBIP_FSDEV +// Temporarily put the check here +#if defined(TUP_USBIP_FSDEV) || defined(TUP_USBIP_DWC2) #define USE_ISO_EP_ALLOCATION 1 #else #define USE_ISO_EP_ALLOCATION 0 diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 3f00243e5..b0149a9a9 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -648,6 +648,108 @@ void dcd_edpt_close_all(uint8_t rhport) { _allocated_fifo_words_tx = 16; } +bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) +{ + (void)rhport; + + TU_ASSERT(largest_packet_size <= 1024); + + dwc2_regs_t* dwc2 = DWC2_REG(rhport); + uint8_t const ep_count = _dwc2_controller[rhport].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 const fifo_size = tu_div_ceil(largest_packet_size, 4); + + if (dir == TUSB_DIR_OUT) { + // Calculate required size of RX FIFO + uint16_t const 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; + } + + } else + { + // "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". + + // 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 %lu", fifo_size * 4, + _dwc2_controller[rhport].ep_fifo_size - _allocated_fifo_words_tx * 4); + + // 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); + } + + return true; +} + +bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) +{ + (void)rhport; + + dwc2_regs_t* dwc2 = DWC2_REG(rhport); + + uint8_t const epnum = tu_edpt_number(p_endpoint_desc->bEndpointAddress); + uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); + + xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, dir); + xfer->max_size = tu_edpt_packet_size(p_endpoint_desc); + xfer->interval = p_endpoint_desc->bInterval; + + if (dir == TUSB_DIR_OUT) { + dwc2->epout[epnum].doepctl |= (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); + + dwc2->daintmsk |= TU_BIT(DAINTMSK_OEPM_Pos + epnum); + } else + { + dwc2->epin[epnum].diepctl |= (1 << DIEPCTL_USBAEP_Pos) | + (epnum << DIEPCTL_TXFNUM_Pos) | + (p_endpoint_desc->bmAttributes.xfer << DIEPCTL_EPTYP_Pos) | + (p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? DIEPCTL_SD0PID_SEVNFRM : 0) | + (xfer->max_size << DIEPCTL_MPSIZ_Pos); + + dwc2->daintmsk |= (1 << (DAINTMSK_IEPM_Pos + epnum)); + } + + return true; +} + bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) { uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); From 4116a962a6c3073e6c617797e3d87643eafc4375 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 23 Nov 2023 19:20:03 +0100 Subject: [PATCH 182/454] Flush FIFO on bus reset. --- src/portable/synopsys/dwc2/dcd_dwc2.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index b0149a9a9..a411b54f4 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -139,6 +139,14 @@ static void bus_reset(uint8_t rhport) { dwc2->epout[n].doepctl |= DOEPCTL_SNAK; } + // flush all TX fifo and wait for it cleared + dwc2->grstctl = GRSTCTL_TXFFLSH | (0x10u << GRSTCTL_TXFNUM_Pos); + while (dwc2->grstctl & GRSTCTL_TXFFLSH_Msk) {} + + // flush RX fifo and wait for it cleared + dwc2->grstctl = GRSTCTL_RXFFLSH; + while (dwc2->grstctl & GRSTCTL_RXFFLSH_Msk) {} + // 2. Set up interrupt mask dwc2->daintmsk = TU_BIT(DAINTMSK_OEPM_Pos) | TU_BIT(DAINTMSK_IEPM_Pos); dwc2->doepmsk = DOEPMSK_STUPM | DOEPMSK_XFRCM; From 8055bc88d8f606c1f69d669a1c022d1a7bca44a2 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 12 Jan 2024 15:59:51 +0100 Subject: [PATCH 183/454] Code refactor. --- src/portable/synopsys/dwc2/dcd_dwc2.c | 375 +++++++++++--------------- 1 file changed, 157 insertions(+), 218 deletions(-) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index a411b54f4..f302b29b3 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -121,6 +121,155 @@ static void update_grxfsiz(uint8_t rhport) { dwc2->grxfsiz = calc_grxfsiz(max_epsize, ep_count); } +static bool fifo_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; + + 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 const fifo_size = tu_div_ceil(packet_size, 4); + + if (dir == TUSB_DIR_OUT) { + // Calculate required size of RX FIFO + uint16_t const 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; + } + + } else + { + // "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". + + // 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 %lu", fifo_size * 4, + _dwc2_controller[rhport].ep_fifo_size - _allocated_fifo_words_tx * 4); + + // 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); + } + + return true; +} + +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); + uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); + + xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, dir); + xfer->max_size = tu_edpt_packet_size(p_endpoint_desc); + xfer->interval = p_endpoint_desc->bInterval; + + if (dir == TUSB_DIR_OUT) { + dwc2->epout[epnum].doepctl |= (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); + + dwc2->daintmsk |= TU_BIT(DAINTMSK_OEPM_Pos + epnum); + } else + { + dwc2->epin[epnum].diepctl |= (1 << DIEPCTL_USBAEP_Pos) | + (epnum << DIEPCTL_TXFNUM_Pos) | + (p_endpoint_desc->bmAttributes.xfer << DIEPCTL_EPTYP_Pos) | + (p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? DIEPCTL_SD0PID_SEVNFRM : 0) | + (xfer->max_size << DIEPCTL_MPSIZ_Pos); + + dwc2->daintmsk |= (1 << (DAINTMSK_IEPM_Pos + epnum)); + } +} + +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); + + 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); + } else { + // Stop transmitting packets and NAK IN xfers. + epin[epnum].diepctl |= DIEPCTL_SNAK; + while ((epin[epnum].diepint & DIEPINT_INEPNE) == 0) {} + + // Disable the endpoint. + epin[epnum].diepctl |= DIEPCTL_EPDIS | (stall ? DIEPCTL_STALL : 0); + while ((epin[epnum].diepint & DIEPINT_EPDISD_Msk) == 0) {} + + epin[epnum].diepint = DIEPINT_EPDISD; + } + + // Flush the FIFO, and wait until we have confirmed it cleared. + dwc2->grstctl = ((epnum << GRSTCTL_TXFNUM_Pos) | GRSTCTL_TXFFLSH); + while ((dwc2->grstctl & GRSTCTL_TXFFLSH_Msk) != 0) {} + } 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; + } else { + // Asserting GONAK is required to STALL an OUT endpoint. + // Simpler to use polling here, we don't use the "B"OUTNAKEFF interrupt + // anyway, and it can't be cleared by user code. If this while loop never + // finishes, we have bigger problems than just the stack. + 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) {} + + epout[epnum].doepint = DOEPINT_EPDISD; + + // Allow other OUT endpoints to keep receiving. + dwc2->dctl |= DCTL_CGONAK; + } + } +} + // Start of Bus Reset static void bus_reset(uint8_t rhport) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); @@ -555,81 +704,9 @@ void dcd_sof_enable(uint8_t rhport, bool en) { bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const* desc_edpt) { (void) rhport; - dwc2_regs_t* dwc2 = DWC2_REG(rhport); - uint8_t const ep_count = _dwc2_controller[rhport].ep_count; + TU_ASSERT(fifo_alloc(rhport, desc_edpt->bEndpointAddress, tu_edpt_packet_size(desc_edpt))); - uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress); - uint8_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); - - TU_ASSERT(epnum < ep_count); - - xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, dir); - xfer->max_size = tu_edpt_packet_size(desc_edpt); - xfer->interval = desc_edpt->bInterval; - - uint16_t const fifo_size = tu_div_ceil(xfer->max_size, 4); - - if (dir == TUSB_DIR_OUT) { - // Calculate required size of RX FIFO - uint16_t const 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; - } - - dwc2->epout[epnum].doepctl |= (1 << DOEPCTL_USBAEP_Pos) | - (desc_edpt->bmAttributes.xfer << DOEPCTL_EPTYP_Pos) | - (desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? DOEPCTL_SD0PID_SEVNFRM : 0) | - (xfer->max_size << DOEPCTL_MPSIZ_Pos); - - dwc2->daintmsk |= TU_BIT(DAINTMSK_OEPM_Pos + epnum); - } else { - // "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". - - // 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 %lu", fifo_size * 4, - _dwc2_controller[rhport].ep_fifo_size - _allocated_fifo_words_tx * 4); - - // 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); - - dwc2->epin[epnum].diepctl |= (1 << DIEPCTL_USBAEP_Pos) | - (epnum << DIEPCTL_TXFNUM_Pos) | - (desc_edpt->bmAttributes.xfer << DIEPCTL_EPTYP_Pos) | - (desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? DIEPCTL_SD0PID_SEVNFRM : 0) | - (xfer->max_size << DIEPCTL_MPSIZ_Pos); - - dwc2->daintmsk |= (1 << (DAINTMSK_IEPM_Pos + epnum)); - } + edpt_activate(rhport, desc_edpt); return true; } @@ -658,102 +735,17 @@ 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; - - TU_ASSERT(largest_packet_size <= 1024); - - dwc2_regs_t* dwc2 = DWC2_REG(rhport); - uint8_t const ep_count = _dwc2_controller[rhport].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 const fifo_size = tu_div_ceil(largest_packet_size, 4); - - if (dir == TUSB_DIR_OUT) { - // Calculate required size of RX FIFO - uint16_t const 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; - } - - } else - { - // "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". - - // 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 %lu", fifo_size * 4, - _dwc2_controller[rhport].ep_fifo_size - _allocated_fifo_words_tx * 4); - - // 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); - } + TU_ASSERT(fifo_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) { - (void)rhport; + // Disable EP to clear potential incomplete transfers + edpt_disable(rhport, p_endpoint_desc->bEndpointAddress, false); - dwc2_regs_t* dwc2 = DWC2_REG(rhport); - - uint8_t const epnum = tu_edpt_number(p_endpoint_desc->bEndpointAddress); - uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); - - xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, dir); - xfer->max_size = tu_edpt_packet_size(p_endpoint_desc); - xfer->interval = p_endpoint_desc->bInterval; - - if (dir == TUSB_DIR_OUT) { - dwc2->epout[epnum].doepctl |= (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); - - dwc2->daintmsk |= TU_BIT(DAINTMSK_OEPM_Pos + epnum); - } else - { - dwc2->epin[epnum].diepctl |= (1 << DIEPCTL_USBAEP_Pos) | - (epnum << DIEPCTL_TXFNUM_Pos) | - (p_endpoint_desc->bmAttributes.xfer << DIEPCTL_EPTYP_Pos) | - (p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? DIEPCTL_SD0PID_SEVNFRM : 0) | - (xfer->max_size << DIEPCTL_MPSIZ_Pos); - - dwc2->daintmsk |= (1 << (DAINTMSK_IEPM_Pos + epnum)); - } + edpt_activate(rhport, p_endpoint_desc); return true; } @@ -815,60 +807,7 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t* ff, uint16_t return true; } -static void dcd_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); - - 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); - } else { - // Stop transmitting packets and NAK IN xfers. - epin[epnum].diepctl |= DIEPCTL_SNAK; - while ((epin[epnum].diepint & DIEPINT_INEPNE) == 0) {} - - // Disable the endpoint. - epin[epnum].diepctl |= DIEPCTL_EPDIS | (stall ? DIEPCTL_STALL : 0); - while ((epin[epnum].diepint & DIEPINT_EPDISD_Msk) == 0) {} - - epin[epnum].diepint = DIEPINT_EPDISD; - } - - // Flush the FIFO, and wait until we have confirmed it cleared. - dwc2->grstctl = ((epnum << GRSTCTL_TXFNUM_Pos) | GRSTCTL_TXFFLSH); - while ((dwc2->grstctl & GRSTCTL_TXFFLSH_Msk) != 0) {} - } 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; - } else { - // Asserting GONAK is required to STALL an OUT endpoint. - // Simpler to use polling here, we don't use the "B"OUTNAKEFF interrupt - // anyway, and it can't be cleared by user code. If this while loop never - // finishes, we have bigger problems than just the stack. - 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) {} - - epout[epnum].doepint = DOEPINT_EPDISD; - - // Allow other OUT endpoints to keep receiving. - dwc2->dctl |= DCTL_CGONAK; - } - } -} /** * Close an endpoint. @@ -879,7 +818,7 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); - dcd_edpt_disable(rhport, ep_addr, false); + edpt_disable(rhport, ep_addr, false); // Update max_size xfer_status[epnum][dir].max_size = 0; // max_size = 0 marks a disabled EP - required for changing FIFO allocation @@ -897,7 +836,7 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { } void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { - dcd_edpt_disable(rhport, ep_addr, true); + edpt_disable(rhport, ep_addr, true); } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { From 85420c61c780e260d0afd21de4a39c17ceba5d87 Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 31 Mar 2024 13:49:41 +0700 Subject: [PATCH 184/454] minor clean up --- src/portable/synopsys/dwc2/dcd_dwc2.c | 104 ++++++++++---------------- 1 file changed, 41 insertions(+), 63 deletions(-) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index f302b29b3..cf8f3be50 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -102,7 +102,13 @@ static bool _out_ep_closed; // Flag to check if RX FIFO size n // 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 recommendations from reference manual +// 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; } @@ -121,11 +127,9 @@ static void update_grxfsiz(uint8_t rhport) { dwc2->grxfsiz = calc_grxfsiz(max_epsize, ep_count); } -static bool fifo_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t packet_size) -{ +static bool fifo_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; - uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); @@ -133,6 +137,26 @@ static bool fifo_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t packet_size) uint16_t const 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); @@ -144,35 +168,10 @@ static bool fifo_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t packet_size) // Enlarge RX FIFO dwc2->grxfsiz = sz; } - - } else - { - // "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". - + } else { // 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 %lu", fifo_size * 4, _dwc2_controller[rhport].ep_fifo_size - _allocated_fifo_words_tx * 4); @@ -185,10 +184,8 @@ static bool fifo_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t packet_size) return true; } -static void edpt_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) -{ +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); uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); @@ -196,21 +193,17 @@ static void edpt_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoi xfer->max_size = tu_edpt_packet_size(p_endpoint_desc); 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 |= (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); - + dwc2->epout[epnum].doepctl |= dxepctl; dwc2->daintmsk |= TU_BIT(DAINTMSK_OEPM_Pos + epnum); - } else - { - dwc2->epin[epnum].diepctl |= (1 << DIEPCTL_USBAEP_Pos) | - (epnum << DIEPCTL_TXFNUM_Pos) | - (p_endpoint_desc->bmAttributes.xfer << DIEPCTL_EPTYP_Pos) | - (p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? DIEPCTL_SD0PID_SEVNFRM : 0) | - (xfer->max_size << DIEPCTL_MPSIZ_Pos); - + } else { + dwc2->epin[epnum].diepctl |= dxepctl | (epnum << DIEPCTL_TXFNUM_Pos); dwc2->daintmsk |= (1 << (DAINTMSK_IEPM_Pos + epnum)); } } @@ -219,7 +212,6 @@ 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); @@ -426,7 +418,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 @@ -437,7 +428,6 @@ void print_dwc2_info(dwc2_regs_t* dwc2) { } TU_LOG(DWC2_DEBUG, "0x%08lX\r\n", p[5]); } - #endif static void reset_core(dwc2_regs_t* dwc2) { @@ -702,12 +692,8 @@ void dcd_sof_enable(uint8_t rhport, bool en) { *------------------------------------------------------------------*/ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const* desc_edpt) { - (void) rhport; - TU_ASSERT(fifo_alloc(rhport, desc_edpt->bEndpointAddress, tu_edpt_packet_size(desc_edpt))); - edpt_activate(rhport, desc_edpt); - return true; } @@ -733,15 +719,12 @@ void dcd_edpt_close_all(uint8_t rhport) { _allocated_fifo_words_tx = 16; } -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) { TU_ASSERT(fifo_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) -{ +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); @@ -807,11 +790,6 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t* ff, uint16_t return true; } - - -/** - * Close an endpoint. - */ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); From 998090d1a7f914c04f0bb3e6ac85634d432d88fc Mon Sep 17 00:00:00 2001 From: IngHK Date: Fri, 29 Mar 2024 15:59:11 +0100 Subject: [PATCH 185/454] added further debug log outputs --- src/portable/analog/max3421/hcd_max3421.c | 32 ++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index d366298ea..93d12fc64 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -29,6 +29,7 @@ #if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 #define NAK_RETRY_HANDLING 1 +#define PUTCHAR_LOGS 0 // TODO to be deleted later #include #include "host/hcd.h" @@ -808,7 +809,11 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) { xfer_result_t xfer_result; switch(hresult) { case HRSL_SUCCESS: -// putchar('S'); +#if PUTCHAR_LOGS // TODO to be deleted later + putchar(ep->ep_dir ? 's' : 'S'); + putchar('0' + ep->daddr); +// putchar('0' + ep->ep_num); +#endif xfer_result = XFER_RESULT_SUCCESS; break; @@ -817,7 +822,12 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) { break; case HRSL_NAK: -// putchar('N'); +#if PUTCHAR_LOGS // TODO to be deleted later + putchar(ep->ep_dir ? 'n' : 'N'); + putchar('0' + ep->daddr); +// putchar('0' + ep->ep_num); +// putchar('0' + ep->xfer_attemp); +#endif #if NAK_RETRY_HANDLING ep->retry_pending = 1; ep->xfer_pending = 0; @@ -928,6 +938,12 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { // print_hirq(hirq); if (hirq & HIRQ_FRAME_IRQ) { + LL_GPIO_SetOutputPin ( D2_GPIO_Port, D2_Pin ); // TODO to be deleted later +#if PUTCHAR_LOGS // TODO to be deleted later + putchar(13); + putchar(10); + putchar('F'); +#endif _hcd_data.frame_count++; #if NAK_RETRY_HANDLING @@ -937,7 +953,11 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { max3421_ep_t * ep = &_hcd_data.ep[i]; // set retryable EPs to pending if (ep->retry_pending) { -// putchar('R'); +#if PUTCHAR_LOGS // TODO to be deleted later + putchar(ep->ep_dir ? 'r' : 'R'); + putchar('0' + ep->daddr); +// putchar('0' + ep->ep_num); +#endif ep->xfer_pending = 1; ep->retry_pending = 0; if (next_ep == NULL) { @@ -948,10 +968,16 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { // trigger 1st retryable EP if (next_ep) { if ( !atomic_flag_test_and_set(&_hcd_data.busy) ) { +#if PUTCHAR_LOGS // TODO to be deleted later + putchar(next_ep->ep_dir ? 't' : 'T'); + putchar('0' + next_ep->daddr); +// putchar('0' + next_ep->ep_num); +#endif xact_inout(rhport, next_ep, true, in_isr); } } #endif + LL_GPIO_SetOutputPin ( D2_GPIO_Port, D2_Pin << 16 ); } if (hirq & HIRQ_CONDET_IRQ) { From 818c64efecfb70d8abfee6b90d53f4af8c452dcf Mon Sep 17 00:00:00 2001 From: IngHK Date: Sat, 30 Mar 2024 14:11:02 +0100 Subject: [PATCH 186/454] fixed EP0 control handling --- src/portable/analog/max3421/hcd_max3421.c | 32 +++++++++++------------ 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index 93d12fc64..9209865d4 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -828,36 +828,36 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) { // putchar('0' + ep->ep_num); // putchar('0' + ep->xfer_attemp); #endif -#if NAK_RETRY_HANDLING - ep->retry_pending = 1; - ep->xfer_pending = 0; - max3421_ep_t * next_ep = find_next_pending_ep(ep); - if (next_ep) { - // switch to next pending TODO could have issue with double buffered if not clear previously out data - xact_inout(rhport, next_ep, true, in_isr); - } else { - // no more pending - atomic_flag_clear(&_hcd_data.busy); - } -#else if (ep_num == 0) { // NAK on control, retry immediately hxfr_write(rhport, _hcd_data.hxfr, in_isr); - }else { + } else { + #if NAK_RETRY_HANDLING + ep->retry_pending = 1; + ep->xfer_pending = 0; + max3421_ep_t * next_ep = find_next_pending_ep(ep); + if (next_ep) { + // switch to next pending TODO could have issue with double buffered if not clear previously out data + xact_inout(rhport, next_ep, true, in_isr); + } else { + // no more pending + atomic_flag_clear(&_hcd_data.busy); + } + #else // NAK on non-control, find next pending to switch 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) { + } else if (next_ep) { // switch to next pending TODO could have issue with double buffered if not clear previously out data xact_inout(rhport, next_ep, true, in_isr); - }else { + } else { TU_ASSERT(false,); } + #endif } -#endif return; case HRSL_BAD_REQ: From 11a54bc8e185c58fa5c72b6913ac07e3a3060be6 Mon Sep 17 00:00:00 2001 From: IngHK Date: Sat, 30 Mar 2024 14:16:13 +0100 Subject: [PATCH 187/454] renamed define NAK_RETRY_HANDLING to CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME as official option --- src/portable/analog/max3421/hcd_max3421.c | 9 +++++---- src/tusb_option.h | 9 +++++++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index 9209865d4..09de1bc5a 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -28,7 +28,6 @@ #if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 -#define NAK_RETRY_HANDLING 1 #define PUTCHAR_LOGS 0 // TODO to be deleted later #include @@ -169,6 +168,8 @@ enum { DEFAULT_HIEN = HIRQ_CONDET_IRQ | HIRQ_FRAME_IRQ | HIRQ_HXFRDN_IRQ | HIRQ_RCVDAV_IRQ }; +TU_VERIFY_STATIC(CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME >= 0 && CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME <= 1, "unsupported attemp quantity"); + //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ @@ -183,7 +184,7 @@ typedef struct { uint8_t data_toggle : 1; uint8_t xfer_pending : 1; uint8_t xfer_complete : 1; -#if NAK_RETRY_HANDLING +#if CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME uint8_t retry_pending : 1; #endif }; @@ -832,7 +833,7 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) { // NAK on control, retry immediately hxfr_write(rhport, _hcd_data.hxfr, in_isr); } else { - #if NAK_RETRY_HANDLING + #if CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME ep->retry_pending = 1; ep->xfer_pending = 0; max3421_ep_t * next_ep = find_next_pending_ep(ep); @@ -946,7 +947,7 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { #endif _hcd_data.frame_count++; -#if NAK_RETRY_HANDLING +#if CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME // retry EPs max3421_ep_t * next_ep = NULL; for (size_t i = 0; i < CFG_TUH_MAX3421_ENDPOINT_TOTAL; i++) { diff --git a/src/tusb_option.h b/src/tusb_option.h index 22f27e9e1..68eb4882c 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -529,6 +529,15 @@ #define CFG_TUH_MAX3421 0 #endif +// MAX3421 Host max. transfer attemps per frame (except control and iso) +// temporary only one attemp (no retry) per frame allowed (more in work) +// retry quantity = (CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME - 1) +// 0 = endless retries in current frame. is default to keep compatibility +#ifndef CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME + #define CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME 0 +#endif + + //--------------------------------------------------------------------+ // TypeC Options (Default) //--------------------------------------------------------------------+ From 009d85722bbfae41f057cfbb69c63716a5fb2c5f Mon Sep 17 00:00:00 2001 From: IngHK Date: Sat, 30 Mar 2024 15:17:34 +0100 Subject: [PATCH 188/454] replaced bits xfer_pending, xfer_complete and retry_pending by common 4 bits state --- src/portable/analog/max3421/hcd_max3421.c | 47 ++++++++++++----------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index 09de1bc5a..2b3c625dc 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -168,6 +168,15 @@ enum { DEFAULT_HIEN = HIRQ_CONDET_IRQ | HIRQ_FRAME_IRQ | HIRQ_HXFRDN_IRQ | HIRQ_RCVDAV_IRQ }; +enum { + EP_STATE_IDLE = 0, + EP_STATE_PENDING, +#if CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME + EP_STATE_SUSPENDED, +#endif + EP_STATE_COMPLETE +}; + TU_VERIFY_STATIC(CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME >= 0 && CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME <= 1, "unsupported attemp quantity"); //--------------------------------------------------------------------+ @@ -178,15 +187,11 @@ typedef struct { uint8_t daddr; struct TU_ATTR_PACKED { - uint8_t ep_dir : 1; - uint8_t is_iso : 1; - uint8_t is_setup : 1; + uint8_t state : 4; + uint8_t is_setup : 1; // also bit 4 in HXFR reg (smaller code, no shift necessary) + uint8_t ep_dir : 1; // also bit 5 in HXFR reg (smaller code, no shift necessary) + uint8_t is_iso : 1; // also bit 6 in HXFR reg (smaller code, no shift necessary) uint8_t data_toggle : 1; - uint8_t xfer_pending : 1; - uint8_t xfer_complete : 1; -#if CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME - uint8_t retry_pending : 1; -#endif }; struct TU_ATTR_PACKED { @@ -406,7 +411,7 @@ static max3421_ep_t * find_next_pending_ep(max3421_ep_t * cur_ep) { // starting from next endpoint for (size_t i = idx + 1; i < CFG_TUH_MAX3421_ENDPOINT_TOTAL; i++) { max3421_ep_t* ep = &_hcd_data.ep[i]; - if (ep->xfer_pending && ep->packet_size) { + if (ep->state == EP_STATE_PENDING && ep->packet_size) { // TU_LOG3("next pending i = %u\r\n", i); return ep; } @@ -415,7 +420,7 @@ static max3421_ep_t * find_next_pending_ep(max3421_ep_t * cur_ep) { // wrap around including current endpoint for (size_t i = 0; i <= idx; i++) { max3421_ep_t* ep = &_hcd_data.ep[i]; - if (ep->xfer_pending && ep->packet_size) { + if (ep->state == EP_STATE_PENDING && ep->packet_size) { // TU_LOG3("next pending i = %u\r\n", i); return ep; } @@ -664,8 +669,7 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t daddr, uint8_t ep_addr, uint8_t * buf ep->buf = buffer; ep->total_len = buflen; ep->xferred_len = 0; - ep->xfer_complete = 0; - ep->xfer_pending = 1; + ep->state = EP_STATE_PENDING; if ( ep_num == 0 ) { ep->is_setup = 0; @@ -704,8 +708,7 @@ bool hcd_setup_send(uint8_t rhport, uint8_t daddr, uint8_t const setup_packet[8] ep->buf = (uint8_t*)(uintptr_t) setup_packet; ep->total_len = 8; ep->xferred_len = 0; - ep->xfer_complete = 0; - ep->xfer_pending = 1; + ep->state = EP_STATE_PENDING; // carry out transfer if not busy if ( !atomic_flag_test_and_set(&_hcd_data.busy) ) { @@ -783,7 +786,7 @@ static void xfer_complete_isr(uint8_t rhport, max3421_ep_t *ep, xfer_result_t re ep->data_toggle = (hrsl & HRSL_SNDTOGRD) ? 1u : 0u; } - ep->xfer_pending = 0; + ep->state = EP_STATE_IDLE; hcd_event_xfer_complete(ep->daddr, ep_addr, ep->xferred_len, result, in_isr); // Find next pending endpoint @@ -834,8 +837,7 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) { hxfr_write(rhport, _hcd_data.hxfr, in_isr); } else { #if CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME - ep->retry_pending = 1; - ep->xfer_pending = 0; + ep->state = EP_STATE_SUSPENDED; max3421_ep_t * next_ep = find_next_pending_ep(ep); if (next_ep) { // switch to next pending TODO could have issue with double buffered if not clear previously out data @@ -879,11 +881,11 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) { if (ep_dir) { // IN transfer: fifo data is already received in RCVDAV IRQ if ( hxfr_type & HXFR_HS ) { - ep->xfer_complete = 1; + ep->state = EP_STATE_COMPLETE; } // short packet or all bytes transferred - if ( ep->xfer_complete ) { + if (ep->state == EP_STATE_COMPLETE) { xfer_complete_isr(rhport, ep, xfer_result, hrsl, in_isr); }else { // more to transfer @@ -953,14 +955,13 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { for (size_t i = 0; i < CFG_TUH_MAX3421_ENDPOINT_TOTAL; i++) { max3421_ep_t * ep = &_hcd_data.ep[i]; // set retryable EPs to pending - if (ep->retry_pending) { + if (ep->state == EP_STATE_SUSPENDED) { #if PUTCHAR_LOGS // TODO to be deleted later putchar(ep->ep_dir ? 'r' : 'R'); putchar('0' + ep->daddr); // putchar('0' + ep->ep_num); #endif - ep->xfer_pending = 1; - ep->retry_pending = 0; + ep->state = EP_STATE_PENDING; if (next_ep == NULL) { next_ep = &_hcd_data.ep[i]; } @@ -1009,7 +1010,7 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { } if ( xact_len < ep->packet_size || ep->xferred_len >= ep->total_len ) { - ep->xfer_complete = 1; + ep->state = EP_STATE_COMPLETE; } } From 0bb26c97c316cbf3dc0b6e70234c958cf361da73 Mon Sep 17 00:00:00 2001 From: IngHK Date: Sat, 30 Mar 2024 14:49:00 +0100 Subject: [PATCH 189/454] removed redundant return true; --- src/portable/analog/max3421/hcd_max3421.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index 2b3c625dc..335d78481 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -679,8 +679,6 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t daddr, uint8_t ep_addr, uint8_t * buf // carry out transfer if not busy if ( !atomic_flag_test_and_set(&_hcd_data.busy) ) { xact_inout(rhport, ep, true, false); - } else { - return true; } return true; From f3fccaad2657fae7957523aee5ec1698b55470c4 Mon Sep 17 00:00:00 2001 From: IngHK Date: Sat, 30 Mar 2024 14:57:22 +0100 Subject: [PATCH 190/454] improved/fixed trigger 1st retryable EP --- src/portable/analog/max3421/hcd_max3421.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index 335d78481..2dc8f2e18 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -949,7 +949,6 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { #if CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME // retry EPs - max3421_ep_t * next_ep = NULL; for (size_t i = 0; i < CFG_TUH_MAX3421_ENDPOINT_TOTAL; i++) { max3421_ep_t * ep = &_hcd_data.ep[i]; // set retryable EPs to pending @@ -960,20 +959,17 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { // putchar('0' + ep->ep_num); #endif ep->state = EP_STATE_PENDING; - if (next_ep == NULL) { - next_ep = &_hcd_data.ep[i]; - } - } - } - // trigger 1st retryable EP - if (next_ep) { - if ( !atomic_flag_test_and_set(&_hcd_data.busy) ) { + // trigger 1st retryable EP + if (ep->packet_size) { // first test packet_size before atomic_flag_test_and_set() + if (!atomic_flag_test_and_set(&_hcd_data.busy) ) { #if PUTCHAR_LOGS // TODO to be deleted later - putchar(next_ep->ep_dir ? 't' : 'T'); - putchar('0' + next_ep->daddr); -// putchar('0' + next_ep->ep_num); + putchar(ep->ep_dir ? 't' : 'T'); + putchar('0' + ep->daddr); +// putchar('0' + ep->ep_num); #endif - xact_inout(rhport, next_ep, true, in_isr); + xact_inout(rhport, ep, true, in_isr); + } + } } } #endif From 79bc09a68ce07224983bf597b29e7fb1084617f3 Mon Sep 17 00:00:00 2001 From: IngHK Date: Sat, 30 Mar 2024 15:15:05 +0100 Subject: [PATCH 191/454] improved code readability --- src/portable/analog/max3421/hcd_max3421.c | 75 +++++++++++------------ 1 file changed, 35 insertions(+), 40 deletions(-) diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index 2dc8f2e18..dbdd2d127 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -788,7 +788,7 @@ static void xfer_complete_isr(uint8_t rhport, max3421_ep_t *ep, xfer_result_t re hcd_event_xfer_complete(ep->daddr, ep_addr, ep->xferred_len, result, in_isr); // Find next pending endpoint - max3421_ep_t *next_ep = find_next_pending_ep(ep); + max3421_ep_t * next_ep = find_next_pending_ep(ep); if (next_ep) { xact_inout(rhport, next_ep, true, in_isr); }else { @@ -811,11 +811,11 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) { xfer_result_t xfer_result; switch(hresult) { case HRSL_SUCCESS: -#if PUTCHAR_LOGS // TODO to be deleted later - putchar(ep->ep_dir ? 's' : 'S'); - putchar('0' + ep->daddr); -// putchar('0' + ep->ep_num); -#endif + #if PUTCHAR_LOGS // TODO to be deleted later + putchar(ep->ep_dir ? 's' : 'S'); + putchar('0' + ep->daddr); +// putchar('0' + ep->ep_num); + #endif xfer_result = XFER_RESULT_SUCCESS; break; @@ -824,12 +824,12 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) { break; case HRSL_NAK: -#if PUTCHAR_LOGS // TODO to be deleted later - putchar(ep->ep_dir ? 'n' : 'N'); - putchar('0' + ep->daddr); -// putchar('0' + ep->ep_num); -// putchar('0' + ep->xfer_attemp); -#endif + #if PUTCHAR_LOGS // TODO to be deleted later + putchar(ep->ep_dir ? 'n' : 'N'); + putchar('0' + ep->daddr); +// putchar('0' + ep->ep_num); + putchar('0' + ep->state); + #endif if (ep_num == 0) { // NAK on control, retry immediately hxfr_write(rhport, _hcd_data.hxfr, in_isr); @@ -917,13 +917,13 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) { void print_hirq(uint8_t hirq) { TU_LOG3_HEX(hirq); - if (hirq & HIRQ_HXFRDN_IRQ) TU_LOG3(" HXFRDN"); - if (hirq & HIRQ_FRAME_IRQ) TU_LOG3(" FRAME"); - if (hirq & HIRQ_CONDET_IRQ) TU_LOG3(" CONDET"); - if (hirq & HIRQ_SUSDN_IRQ) TU_LOG3(" SUSDN"); - if (hirq & HIRQ_SNDBAV_IRQ) TU_LOG3(" SNDBAV"); - if (hirq & HIRQ_RCVDAV_IRQ) TU_LOG3(" RCVDAV"); - if (hirq & HIRQ_RWU_IRQ) TU_LOG3(" RWU"); + if (hirq & HIRQ_HXFRDN_IRQ) TU_LOG3(" HXFRDN"); + if (hirq & HIRQ_FRAME_IRQ) TU_LOG3(" FRAME"); + if (hirq & HIRQ_CONDET_IRQ) TU_LOG3(" CONDET"); + if (hirq & HIRQ_SUSDN_IRQ) TU_LOG3(" SUSDN"); + if (hirq & HIRQ_SNDBAV_IRQ) TU_LOG3(" SNDBAV"); + if (hirq & HIRQ_RCVDAV_IRQ) TU_LOG3(" RCVDAV"); + if (hirq & HIRQ_RWU_IRQ) TU_LOG3(" RWU"); if (hirq & HIRQ_BUSEVENT_IRQ) TU_LOG3(" BUSEVENT"); TU_LOG3("\r\n"); @@ -940,33 +940,28 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { if (hirq & HIRQ_FRAME_IRQ) { LL_GPIO_SetOutputPin ( D2_GPIO_Port, D2_Pin ); // TODO to be deleted later -#if PUTCHAR_LOGS // TODO to be deleted later - putchar(13); - putchar(10); - putchar('F'); -#endif + #if PUTCHAR_LOGS // TODO to be deleted later + putchar(13); + putchar(10); + putchar('F'); + #endif _hcd_data.frame_count++; -#if CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME - // retry EPs - for (size_t i = 0; i < CFG_TUH_MAX3421_ENDPOINT_TOTAL; i++) { - max3421_ep_t * ep = &_hcd_data.ep[i]; - // set retryable EPs to pending - if (ep->state == EP_STATE_SUSPENDED) { -#if PUTCHAR_LOGS // TODO to be deleted later - putchar(ep->ep_dir ? 'r' : 'R'); - putchar('0' + ep->daddr); -// putchar('0' + ep->ep_num); -#endif + #if CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME + // retry EPs + for (size_t i = 0; i < CFG_TUH_MAX3421_ENDPOINT_TOTAL; i++) { + max3421_ep_t * ep = &_hcd_data.ep[i]; + // set retryable EPs to pending + if (ep->state == EP_STATE_SUSPENDED) { ep->state = EP_STATE_PENDING; // trigger 1st retryable EP if (ep->packet_size) { // first test packet_size before atomic_flag_test_and_set() if (!atomic_flag_test_and_set(&_hcd_data.busy) ) { -#if PUTCHAR_LOGS // TODO to be deleted later - putchar(ep->ep_dir ? 't' : 'T'); - putchar('0' + ep->daddr); -// putchar('0' + ep->ep_num); -#endif + #if PUTCHAR_LOGS // TODO to be deleted later + putchar(ep->ep_dir ? 't' : 'T'); + putchar('0' + ep->daddr); +// putchar('0' + ep->ep_num); + #endif xact_inout(rhport, ep, true, in_isr); } } From fbb2818864d70e7e11879bf1c2daf2c22011f78b Mon Sep 17 00:00:00 2001 From: IngHK Date: Sun, 31 Mar 2024 09:25:51 +0200 Subject: [PATCH 192/454] added multiple attemp counting per frame --- src/portable/analog/max3421/hcd_max3421.c | 100 +++++++++++++++------- 1 file changed, 70 insertions(+), 30 deletions(-) diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index dbdd2d127..6a38302b1 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -169,15 +169,33 @@ enum { }; enum { - EP_STATE_IDLE = 0, - EP_STATE_PENDING, -#if CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME - EP_STATE_SUSPENDED, -#endif - EP_STATE_COMPLETE + EP_STATE_IDLE = 0, + EP_STATE_ATTEMP1 = 1, // pending 1st attemp + #if CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME + EP_STATE_ATTEMP2 = 2, // don't change order + EP_STATE_ATTEMP3 = 3, // need to be incrementable + EP_STATE_ATTEMP4 = 4, + EP_STATE_ATTEMP5 = 5, + EP_STATE_ATTEMP6 = 6, + EP_STATE_ATTEMP7 = 7, + EP_STATE_ATTEMP8 = 8, + EP_STATE_ATTEMP9 = 9, + EP_STATE_ATTEMP10 = 10, + EP_STATE_SUSPENDED, // keep next behind last attemp + #endif + EP_STATE_COMPLETE, + EP_STATE_QUANTITY // not used. only to get quantity. keep last }; -TU_VERIFY_STATIC(CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME >= 0 && CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME <= 1, "unsupported attemp quantity"); +TU_VERIFY_STATIC(EP_STATE_QUANTITY <= 16, "no more than 16 states possible. ep->state has 4 bits"); + +#if CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME + #define EP_STATE_ATTEMP_QUANTITY (EP_STATE_SUSPENDED - 1) + TU_VERIFY_STATIC(CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME >= 1 && + CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME <= EP_STATE_ATTEMP_QUANTITY, "unsupported attemp quantity"); +#else + #define EP_STATE_ATTEMP_QUANTITY 1 +#endif //--------------------------------------------------------------------+ // @@ -406,12 +424,16 @@ static void free_ep(uint8_t daddr) { } static max3421_ep_t * find_next_pending_ep(max3421_ep_t * cur_ep) { + // search for next pending endpoint using round-robin scheduling + // if no other endpoint is pending and current endpoint is still pending, the current endpoint will be returned + // if no other endpoint is pending and current endpoint is not pending, NULL will be returned + // TODO maybe priorization control/interrupt/bulk/iso size_t const idx = (size_t) (cur_ep - _hcd_data.ep); // starting from next endpoint for (size_t i = idx + 1; i < CFG_TUH_MAX3421_ENDPOINT_TOTAL; i++) { max3421_ep_t* ep = &_hcd_data.ep[i]; - if (ep->state == EP_STATE_PENDING && ep->packet_size) { + if (ep->state >= EP_STATE_ATTEMP1 && ep->state <= EP_STATE_ATTEMP_QUANTITY && ep->packet_size) { // TU_LOG3("next pending i = %u\r\n", i); return ep; } @@ -420,7 +442,7 @@ static max3421_ep_t * find_next_pending_ep(max3421_ep_t * cur_ep) { // wrap around including current endpoint for (size_t i = 0; i <= idx; i++) { max3421_ep_t* ep = &_hcd_data.ep[i]; - if (ep->state == EP_STATE_PENDING && ep->packet_size) { + if (ep->state >= EP_STATE_ATTEMP1 && ep->state <= EP_STATE_ATTEMP_QUANTITY && ep->packet_size) { // TU_LOG3("next pending i = %u\r\n", i); return ep; } @@ -669,7 +691,7 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t daddr, uint8_t ep_addr, uint8_t * buf ep->buf = buffer; ep->total_len = buflen; ep->xferred_len = 0; - ep->state = EP_STATE_PENDING; + ep->state = EP_STATE_ATTEMP1; if ( ep_num == 0 ) { ep->is_setup = 0; @@ -706,7 +728,7 @@ bool hcd_setup_send(uint8_t rhport, uint8_t daddr, uint8_t const setup_packet[8] ep->buf = (uint8_t*)(uintptr_t) setup_packet; ep->total_len = 8; ep->xferred_len = 0; - ep->state = EP_STATE_PENDING; + ep->state = EP_STATE_ATTEMP1; // carry out transfer if not busy if ( !atomic_flag_test_and_set(&_hcd_data.busy) ) { @@ -824,6 +846,8 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) { break; case HRSL_NAK: + // TODO no retry for iso in current frame + // TODO retry limitation over all (not only per frame) #if PUTCHAR_LOGS // TODO to be deleted later putchar(ep->ep_dir ? 'n' : 'N'); putchar('0' + ep->daddr); @@ -831,33 +855,38 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) { putchar('0' + ep->state); #endif if (ep_num == 0) { - // NAK on control, retry immediately + // setup/control => retry immediately hxfr_write(rhport, _hcd_data.hxfr, in_isr); - } else { #if CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME + } else if (ep->state == CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME) { + // no more retry this frame if max. attemps are reached => suspend and retry it next frame ep->state = EP_STATE_SUSPENDED; + max3421_ep_t * next_ep = find_next_pending_ep(ep); if (next_ep) { - // switch to next pending TODO could have issue with double buffered if not clear previously out data + // switch to next pending endpoint TODO could have issue with double buffered if not clear previously out data xact_inout(rhport, next_ep, true, in_isr); } else { - // no more pending + // no more pending => clear busy atomic_flag_clear(&_hcd_data.busy); } - #else - // NAK on non-control, find next pending to switch - max3421_ep_t *next_ep = find_next_pending_ep(ep); + #endif + } else { + // another attemp + #if CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME + ep->state++; + #endif + max3421_ep_t * next_ep = find_next_pending_ep(ep); if (ep == next_ep) { - // this endpoint is only one pending, retry immediately + // this endpoint is only one pending => retry immediately hxfr_write(rhport, _hcd_data.hxfr, in_isr); } else if (next_ep) { - // switch to next pending TODO could have issue with double buffered if not clear previously out data + // switch to next pending endpoint TODO could have issue with double buffered if not clear previously out data xact_inout(rhport, next_ep, true, in_isr); } else { TU_ASSERT(false,); } - #endif } return; @@ -948,26 +977,37 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { _hcd_data.frame_count++; #if CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME - // retry EPs + // endpoints retry or restart attemp next frame for (size_t i = 0; i < CFG_TUH_MAX3421_ENDPOINT_TOTAL; i++) { max3421_ep_t * ep = &_hcd_data.ep[i]; - // set retryable EPs to pending + + // retry the endpoints that are suspended (NAK) last frame if (ep->state == EP_STATE_SUSPENDED) { - ep->state = EP_STATE_PENDING; - // trigger 1st retryable EP - if (ep->packet_size) { // first test packet_size before atomic_flag_test_and_set() - if (!atomic_flag_test_and_set(&_hcd_data.busy) ) { + // resume and retry suspended endpoint with attemp 1 + ep->state = EP_STATE_ATTEMP1; + + if (ep->packet_size) { // first test packet_size before atomic_flag_test_and_set() + if (!atomic_flag_test_and_set(&_hcd_data.busy) ) { + // trigger endpoint to be retried #if PUTCHAR_LOGS // TODO to be deleted later putchar(ep->ep_dir ? 't' : 'T'); putchar('0' + ep->daddr); // putchar('0' + ep->ep_num); #endif - xact_inout(rhport, ep, true, in_isr); + xact_inout(rhport, ep, true, in_isr); + } } + } else if (ep->state > EP_STATE_ATTEMP1 && ep->state <= CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME) { + // restart all other running/pending endpoints + #if PUTCHAR_LOGS // TODO to be deleted later + putchar(ep->ep_dir ? 'r' : 'R'); + putchar('0' + ep->daddr); +// putchar('0' + ep->ep_num); + #endif + ep->state = EP_STATE_ATTEMP1; } } - } -#endif + #endif LL_GPIO_SetOutputPin ( D2_GPIO_Port, D2_Pin << 16 ); } From c1a17a7369e326fad83b28d2abdef35d61d1f1ab Mon Sep 17 00:00:00 2001 From: IngHK Date: Sun, 31 Mar 2024 09:32:41 +0200 Subject: [PATCH 193/454] removed debug code --- src/portable/analog/max3421/hcd_max3421.c | 30 ----------------------- 1 file changed, 30 deletions(-) diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index 6a38302b1..17d144c07 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -28,8 +28,6 @@ #if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 -#define PUTCHAR_LOGS 0 // TODO to be deleted later - #include #include "host/hcd.h" @@ -833,11 +831,6 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) { xfer_result_t xfer_result; switch(hresult) { case HRSL_SUCCESS: - #if PUTCHAR_LOGS // TODO to be deleted later - putchar(ep->ep_dir ? 's' : 'S'); - putchar('0' + ep->daddr); -// putchar('0' + ep->ep_num); - #endif xfer_result = XFER_RESULT_SUCCESS; break; @@ -848,12 +841,6 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) { case HRSL_NAK: // TODO no retry for iso in current frame // TODO retry limitation over all (not only per frame) - #if PUTCHAR_LOGS // TODO to be deleted later - putchar(ep->ep_dir ? 'n' : 'N'); - putchar('0' + ep->daddr); -// putchar('0' + ep->ep_num); - putchar('0' + ep->state); - #endif if (ep_num == 0) { // setup/control => retry immediately hxfr_write(rhport, _hcd_data.hxfr, in_isr); @@ -968,12 +955,6 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { // print_hirq(hirq); if (hirq & HIRQ_FRAME_IRQ) { - LL_GPIO_SetOutputPin ( D2_GPIO_Port, D2_Pin ); // TODO to be deleted later - #if PUTCHAR_LOGS // TODO to be deleted later - putchar(13); - putchar(10); - putchar('F'); - #endif _hcd_data.frame_count++; #if CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME @@ -989,26 +970,15 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { if (ep->packet_size) { // first test packet_size before atomic_flag_test_and_set() if (!atomic_flag_test_and_set(&_hcd_data.busy) ) { // trigger endpoint to be retried - #if PUTCHAR_LOGS // TODO to be deleted later - putchar(ep->ep_dir ? 't' : 'T'); - putchar('0' + ep->daddr); -// putchar('0' + ep->ep_num); - #endif xact_inout(rhport, ep, true, in_isr); } } } else if (ep->state > EP_STATE_ATTEMP1 && ep->state <= CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME) { // restart all other running/pending endpoints - #if PUTCHAR_LOGS // TODO to be deleted later - putchar(ep->ep_dir ? 'r' : 'R'); - putchar('0' + ep->daddr); -// putchar('0' + ep->ep_num); - #endif ep->state = EP_STATE_ATTEMP1; } } #endif - LL_GPIO_SetOutputPin ( D2_GPIO_Port, D2_Pin << 16 ); } if (hirq & HIRQ_CONDET_IRQ) { From 8ded6d3d2eeb57dbffe1db9cdacaf3ae7c0159a7 Mon Sep 17 00:00:00 2001 From: IngHK Date: Sun, 31 Mar 2024 09:33:20 +0200 Subject: [PATCH 194/454] added some description to tusb_option.h --- src/tusb_option.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/tusb_option.h b/src/tusb_option.h index 68eb4882c..64915cf62 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -530,9 +530,11 @@ #endif // MAX3421 Host max. transfer attemps per frame (except control and iso) -// temporary only one attemp (no retry) per frame allowed (more in work) // retry quantity = (CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME - 1) -// 0 = endless retries in current frame. is default to keep compatibility +// 0 = endless retries. is default to keep compatibility +// => this may overload MCU with permanently repeating NAK interrupts +// => possible increased USB traffic, increased latencies, reduced data throughput +// a usual attemp quantity is 3 (reference: the book "USB Complete" by Jan Axelson) #ifndef CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME #define CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME 0 #endif From 37cce8746d7b3b80bf9a19917bf9a2e3c6d85e8c Mon Sep 17 00:00:00 2001 From: IngHK Date: Sat, 30 Mar 2024 16:38:25 +0100 Subject: [PATCH 195/454] updated all tusb_config.h --- examples/host/bare_api/src/tusb_config.h | 1 + examples/host/cdc_msc_hid/src/tusb_config.h | 1 + examples/host/cdc_msc_hid_freertos/src/tusb_config.h | 1 + examples/host/hid_controller/src/tusb_config.h | 1 + examples/host/msc_file_explorer/src/tusb_config.h | 1 + 5 files changed, 5 insertions(+) diff --git a/examples/host/bare_api/src/tusb_config.h b/examples/host/bare_api/src/tusb_config.h index 432446e94..8bdcb4fba 100644 --- a/examples/host/bare_api/src/tusb_config.h +++ b/examples/host/bare_api/src/tusb_config.h @@ -72,6 +72,7 @@ #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 + // #define CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME 3 // max. transfer attemps per frame // 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) diff --git a/examples/host/cdc_msc_hid/src/tusb_config.h b/examples/host/cdc_msc_hid/src/tusb_config.h index a59a0ffb9..371ed807e 100644 --- a/examples/host/cdc_msc_hid/src/tusb_config.h +++ b/examples/host/cdc_msc_hid/src/tusb_config.h @@ -72,6 +72,7 @@ #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 + // #define CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME 3 // max. transfer attemps per frame // 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) 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..621b97865 100644 --- a/examples/host/cdc_msc_hid_freertos/src/tusb_config.h +++ b/examples/host/cdc_msc_hid_freertos/src/tusb_config.h @@ -77,6 +77,7 @@ #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 + // #define CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME 3 // max. transfer attemps per frame // 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) diff --git a/examples/host/hid_controller/src/tusb_config.h b/examples/host/hid_controller/src/tusb_config.h index 3ac591d8f..8036e9f66 100644 --- a/examples/host/hid_controller/src/tusb_config.h +++ b/examples/host/hid_controller/src/tusb_config.h @@ -72,6 +72,7 @@ #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 + // #define CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME 3 // max. transfer attemps per frame // 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) diff --git a/examples/host/msc_file_explorer/src/tusb_config.h b/examples/host/msc_file_explorer/src/tusb_config.h index c798b4383..3ac3f3cdf 100644 --- a/examples/host/msc_file_explorer/src/tusb_config.h +++ b/examples/host/msc_file_explorer/src/tusb_config.h @@ -72,6 +72,7 @@ #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 + // #define CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME 3 // max. transfer attemps per frame // 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) From fe304576d0875646a07ab56493f27a7a249ded35 Mon Sep 17 00:00:00 2001 From: IngHK Date: Sun, 31 Mar 2024 09:35:38 +0200 Subject: [PATCH 196/454] reactivated TU_ASSERT(_hcd_data.hirq & HIRQ_SNDBAV_IRQ,); --- src/portable/analog/max3421/hcd_max3421.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index 17d144c07..84ea39d20 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -625,7 +625,7 @@ void xact_out(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool 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,); + TU_ASSERT(_hcd_data.hirq & HIRQ_SNDBAV_IRQ,); if (xact_len) { fifo_write(rhport, SNDFIFO_ADDR, ep->buf, xact_len, in_isr); } From b644e4d95582748dfc9ab947bbb32fd994f34448 Mon Sep 17 00:00:00 2001 From: IngHK Date: Sun, 31 Mar 2024 09:58:59 +0200 Subject: [PATCH 197/454] fixed spelling --- examples/host/bare_api/src/tusb_config.h | 2 +- examples/host/cdc_msc_hid/src/tusb_config.h | 2 +- .../cdc_msc_hid_freertos/src/tusb_config.h | 2 +- .../host/hid_controller/src/tusb_config.h | 2 +- .../host/msc_file_explorer/src/tusb_config.h | 2 +- src/portable/analog/max3421/hcd_max3421.c | 68 +++++++++---------- src/tusb_option.h | 8 +-- 7 files changed, 43 insertions(+), 43 deletions(-) diff --git a/examples/host/bare_api/src/tusb_config.h b/examples/host/bare_api/src/tusb_config.h index 8bdcb4fba..d8e81aa82 100644 --- a/examples/host/bare_api/src/tusb_config.h +++ b/examples/host/bare_api/src/tusb_config.h @@ -72,7 +72,7 @@ #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 - // #define CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME 3 // max. transfer attemps per frame + // #define CFG_TUH_MAX3421_MAX_ATTEMPTS_PER_FRAME 3 // max. transfer attempts per frame // 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) diff --git a/examples/host/cdc_msc_hid/src/tusb_config.h b/examples/host/cdc_msc_hid/src/tusb_config.h index 371ed807e..8a56ebc2b 100644 --- a/examples/host/cdc_msc_hid/src/tusb_config.h +++ b/examples/host/cdc_msc_hid/src/tusb_config.h @@ -72,7 +72,7 @@ #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 - // #define CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME 3 // max. transfer attemps per frame + // #define CFG_TUH_MAX3421_MAX_ATTEMPTS_PER_FRAME 3 // max. transfer attempts per frame // 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) 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 621b97865..7705be5c8 100644 --- a/examples/host/cdc_msc_hid_freertos/src/tusb_config.h +++ b/examples/host/cdc_msc_hid_freertos/src/tusb_config.h @@ -77,7 +77,7 @@ #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 - // #define CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME 3 // max. transfer attemps per frame + // #define CFG_TUH_MAX3421_MAX_ATTEMPTS_PER_FRAME 3 // max. transfer attempts per frame // 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) diff --git a/examples/host/hid_controller/src/tusb_config.h b/examples/host/hid_controller/src/tusb_config.h index 8036e9f66..f087a93cf 100644 --- a/examples/host/hid_controller/src/tusb_config.h +++ b/examples/host/hid_controller/src/tusb_config.h @@ -72,7 +72,7 @@ #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 - // #define CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME 3 // max. transfer attemps per frame + // #define CFG_TUH_MAX3421_MAX_ATTEMPTS_PER_FRAME 3 // max. transfer attempts per frame // 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) diff --git a/examples/host/msc_file_explorer/src/tusb_config.h b/examples/host/msc_file_explorer/src/tusb_config.h index 3ac3f3cdf..05b9fa174 100644 --- a/examples/host/msc_file_explorer/src/tusb_config.h +++ b/examples/host/msc_file_explorer/src/tusb_config.h @@ -72,7 +72,7 @@ #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 - // #define CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME 3 // max. transfer attemps per frame + // #define CFG_TUH_MAX3421_MAX_ATTEMPTS_PER_FRAME 3 // max. transfer attempts per frame // 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) diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index 84ea39d20..324638cb8 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -167,19 +167,19 @@ enum { }; enum { - EP_STATE_IDLE = 0, - EP_STATE_ATTEMP1 = 1, // pending 1st attemp - #if CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME - EP_STATE_ATTEMP2 = 2, // don't change order - EP_STATE_ATTEMP3 = 3, // need to be incrementable - EP_STATE_ATTEMP4 = 4, - EP_STATE_ATTEMP5 = 5, - EP_STATE_ATTEMP6 = 6, - EP_STATE_ATTEMP7 = 7, - EP_STATE_ATTEMP8 = 8, - EP_STATE_ATTEMP9 = 9, - EP_STATE_ATTEMP10 = 10, - EP_STATE_SUSPENDED, // keep next behind last attemp + EP_STATE_IDLE = 0, + EP_STATE_ATTEMPT1 = 1, // pending 1st attempt + #if CFG_TUH_MAX3421_MAX_ATTEMPTS_PER_FRAME + EP_STATE_ATTEMPT2 = 2, // don't change order + EP_STATE_ATTEMPT3 = 3, // need to be incrementable + EP_STATE_ATTEMPT4 = 4, + EP_STATE_ATTEMPT5 = 5, + EP_STATE_ATTEMPT6 = 6, + EP_STATE_ATTEMPT7 = 7, + EP_STATE_ATTEMPT8 = 8, + EP_STATE_ATTEMPT9 = 9, + EP_STATE_ATTEMPT10 = 10, + EP_STATE_SUSPENDED, // keep next behind last attempt #endif EP_STATE_COMPLETE, EP_STATE_QUANTITY // not used. only to get quantity. keep last @@ -187,12 +187,12 @@ enum { TU_VERIFY_STATIC(EP_STATE_QUANTITY <= 16, "no more than 16 states possible. ep->state has 4 bits"); -#if CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME - #define EP_STATE_ATTEMP_QUANTITY (EP_STATE_SUSPENDED - 1) - TU_VERIFY_STATIC(CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME >= 1 && - CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME <= EP_STATE_ATTEMP_QUANTITY, "unsupported attemp quantity"); +#if CFG_TUH_MAX3421_MAX_ATTEMPTS_PER_FRAME + #define EP_STATE_ATTEMPT_QUANTITY (EP_STATE_SUSPENDED - 1) + TU_VERIFY_STATIC(CFG_TUH_MAX3421_MAX_ATTEMPTS_PER_FRAME >= 1 && + CFG_TUH_MAX3421_MAX_ATTEMPTS_PER_FRAME <= EP_STATE_ATTEMPT_QUANTITY, "unsupported attempt quantity"); #else - #define EP_STATE_ATTEMP_QUANTITY 1 + #define EP_STATE_ATTEMPT_QUANTITY 1 #endif //--------------------------------------------------------------------+ @@ -425,13 +425,13 @@ static max3421_ep_t * find_next_pending_ep(max3421_ep_t * cur_ep) { // search for next pending endpoint using round-robin scheduling // if no other endpoint is pending and current endpoint is still pending, the current endpoint will be returned // if no other endpoint is pending and current endpoint is not pending, NULL will be returned - // TODO maybe priorization control/interrupt/bulk/iso + // TODO maybe prioritisation control/interrupt/bulk/iso size_t const idx = (size_t) (cur_ep - _hcd_data.ep); // starting from next endpoint for (size_t i = idx + 1; i < CFG_TUH_MAX3421_ENDPOINT_TOTAL; i++) { max3421_ep_t* ep = &_hcd_data.ep[i]; - if (ep->state >= EP_STATE_ATTEMP1 && ep->state <= EP_STATE_ATTEMP_QUANTITY && ep->packet_size) { + if (ep->state >= EP_STATE_ATTEMPT1 && ep->state <= EP_STATE_ATTEMPT_QUANTITY && ep->packet_size) { // TU_LOG3("next pending i = %u\r\n", i); return ep; } @@ -440,7 +440,7 @@ static max3421_ep_t * find_next_pending_ep(max3421_ep_t * cur_ep) { // wrap around including current endpoint for (size_t i = 0; i <= idx; i++) { max3421_ep_t* ep = &_hcd_data.ep[i]; - if (ep->state >= EP_STATE_ATTEMP1 && ep->state <= EP_STATE_ATTEMP_QUANTITY && ep->packet_size) { + if (ep->state >= EP_STATE_ATTEMPT1 && ep->state <= EP_STATE_ATTEMPT_QUANTITY && ep->packet_size) { // TU_LOG3("next pending i = %u\r\n", i); return ep; } @@ -689,7 +689,7 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t daddr, uint8_t ep_addr, uint8_t * buf ep->buf = buffer; ep->total_len = buflen; ep->xferred_len = 0; - ep->state = EP_STATE_ATTEMP1; + ep->state = EP_STATE_ATTEMPT1; if ( ep_num == 0 ) { ep->is_setup = 0; @@ -726,7 +726,7 @@ bool hcd_setup_send(uint8_t rhport, uint8_t daddr, uint8_t const setup_packet[8] ep->buf = (uint8_t*)(uintptr_t) setup_packet; ep->total_len = 8; ep->xferred_len = 0; - ep->state = EP_STATE_ATTEMP1; + ep->state = EP_STATE_ATTEMPT1; // carry out transfer if not busy if ( !atomic_flag_test_and_set(&_hcd_data.busy) ) { @@ -844,9 +844,9 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) { if (ep_num == 0) { // setup/control => retry immediately hxfr_write(rhport, _hcd_data.hxfr, in_isr); - #if CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME - } else if (ep->state == CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME) { - // no more retry this frame if max. attemps are reached => suspend and retry it next frame + #if CFG_TUH_MAX3421_MAX_ATTEMPTS_PER_FRAME + } else if (ep->state == CFG_TUH_MAX3421_MAX_ATTEMPTS_PER_FRAME) { + // no more retry this frame if max. attempts are reached => suspend and retry it next frame ep->state = EP_STATE_SUSPENDED; max3421_ep_t * next_ep = find_next_pending_ep(ep); @@ -859,8 +859,8 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) { } #endif } else { - // another attemp - #if CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME + // another attempt + #if CFG_TUH_MAX3421_MAX_ATTEMPTS_PER_FRAME ep->state++; #endif @@ -957,15 +957,15 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { if (hirq & HIRQ_FRAME_IRQ) { _hcd_data.frame_count++; - #if CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME - // endpoints retry or restart attemp next frame + #if CFG_TUH_MAX3421_MAX_ATTEMPTS_PER_FRAME + // endpoints retry or restart attempt next frame for (size_t i = 0; i < CFG_TUH_MAX3421_ENDPOINT_TOTAL; i++) { max3421_ep_t * ep = &_hcd_data.ep[i]; // retry the endpoints that are suspended (NAK) last frame if (ep->state == EP_STATE_SUSPENDED) { - // resume and retry suspended endpoint with attemp 1 - ep->state = EP_STATE_ATTEMP1; + // resume and retry suspended endpoint with attempt 1 + ep->state = EP_STATE_ATTEMPT1; if (ep->packet_size) { // first test packet_size before atomic_flag_test_and_set() if (!atomic_flag_test_and_set(&_hcd_data.busy) ) { @@ -973,9 +973,9 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { xact_inout(rhport, ep, true, in_isr); } } - } else if (ep->state > EP_STATE_ATTEMP1 && ep->state <= CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME) { + } else if (ep->state > EP_STATE_ATTEMPT1 && ep->state <= CFG_TUH_MAX3421_MAX_ATTEMPTS_PER_FRAME) { // restart all other running/pending endpoints - ep->state = EP_STATE_ATTEMP1; + ep->state = EP_STATE_ATTEMPT1; } } #endif diff --git a/src/tusb_option.h b/src/tusb_option.h index 64915cf62..18cc8a82c 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -529,14 +529,14 @@ #define CFG_TUH_MAX3421 0 #endif -// MAX3421 Host max. transfer attemps per frame (except control and iso) +// MAX3421 Host max. transfer attempts per frame (except control and iso) // retry quantity = (CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME - 1) // 0 = endless retries. is default to keep compatibility // => this may overload MCU with permanently repeating NAK interrupts // => possible increased USB traffic, increased latencies, reduced data throughput -// a usual attemp quantity is 3 (reference: the book "USB Complete" by Jan Axelson) -#ifndef CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME - #define CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME 0 +// a usual attempt quantity is 3 (reference: the book "USB Complete" by Jan Axelson) +#ifndef CFG_TUH_MAX3421_MAX_ATTEMPTS_PER_FRAME + #define CFG_TUH_MAX3421_MAX_ATTEMPTS_PER_FRAME 0 #endif From 2012a0d369badbc671ac061184ddc3f5961e985e Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 31 Mar 2024 15:48:26 +0700 Subject: [PATCH 198/454] fix hid close not clear data --- src/class/hid/hid_host.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index efc54656e..621fb2a55 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -410,8 +410,7 @@ void hidh_close(uint8_t daddr) { if (p_hid->daddr == daddr) { TU_LOG_DRV(" HIDh close addr = %u index = %u\r\n", daddr, i); if (tuh_hid_umount_cb) tuh_hid_umount_cb(daddr, i); - p_hid->daddr = 0; - p_hid->mounted = false; + tu_memclr(p_hid, sizeof(hidh_interface_t)); } } } From ac4e649e56b7ace537670d1cc261a64a4e650d02 Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 31 Mar 2024 18:41:59 +0700 Subject: [PATCH 199/454] code format --- .../st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h | 176 +++++++----------- 1 file changed, 71 insertions(+), 105 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h index ade64b4fb..15de95d23 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h @@ -1,30 +1,32 @@ -/** - * Copyright(c) 2016 STMicroelectronics - * Copyright(c) N Conrad - * - * 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. - * - */ +/* + * 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. @@ -138,7 +140,6 @@ #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) @@ -182,27 +183,23 @@ 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) -{ +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) -{ +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) -{ +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) -{ +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; @@ -213,9 +210,7 @@ TU_ATTR_ALWAYS_INLINE static inline uint16_t pcd_aligned_buffer_size(uint16_t si return numblocks * blocksize; } -/* SetENDPOINT */ -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 bEpIdx, uint32_t wRegValue) { #ifdef FSDEV_BUS_32BIT (void) USBx; __O uint32_t *reg = (__O uint32_t *)(USB_DRD_BASE + bEpIdx*4); @@ -226,7 +221,6 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_endpoint(USB_TypeDef * USBx, ui #endif } -/* GetENDPOINT */ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_endpoint(USB_TypeDef * USBx, uint32_t bEpIdx) { #ifdef FSDEV_BUS_32BIT (void) USBx; @@ -237,8 +231,7 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_endpoint(USB_TypeDef * USBx return *reg; } -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_eptype(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wType) -{ +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; @@ -246,20 +239,19 @@ 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) -{ +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) -{ +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; @@ -267,22 +259,21 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_rx_ep_ctr(USB_TypeDef * USBx, pcd_set_endpoint(USBx, bEpIdx, regVal); } -TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx, uint32_t bEpIdx) -{ +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) -{ +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; @@ -292,8 +283,7 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_cnt(USB_TypeDef * USB #endif } -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx) -{ +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; /* WA: few cycles for RX PMA descriptor to update, otherwise doesn't return the correct value. @@ -320,8 +310,7 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_cnt(USB_TypeDef * USB * @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) -{ +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; @@ -329,8 +318,7 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_address(USB_TypeDef * USBx, 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) -{ +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 ; @@ -339,8 +327,7 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_address(USB_TypeDef * #endif } -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx) -{ +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; @@ -349,8 +336,7 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_address(USB_TypeDef * #endif } -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) -{ +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); @@ -359,8 +345,7 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_address(USB_TypeDef * USB #endif } -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) -{ +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); @@ -369,8 +354,7 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_address(USB_TypeDef * USB #endif } -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) -{ +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); @@ -380,8 +364,7 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_cnt(USB_TypeDef * USBx, u #endif } -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) -{ +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_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); @@ -391,8 +374,8 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_cnt(USB_TypeDef * USBx, u #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) -{ +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; @@ -403,8 +386,7 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_blsize_num_blocks(USB_TypeDe #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 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. */ @@ -418,13 +400,11 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_bufsize(USB_TypeDef * USBx, pcd_set_ep_blsize_num_blocks(USBx, rxtx_idx, blocksize, numblocks); } -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_bufsize(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) -{ +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_bufsize(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_bufsize(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) -{ +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_bufsize(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { pcd_set_ep_bufsize(USBx, 2*bEpIdx + 1, wCount); } @@ -435,8 +415,7 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_bufsize(USB_TypeDef * USB * @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) -{ +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; @@ -453,7 +432,7 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_status(USB_TypeDef * USBx regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; pcd_set_endpoint(USBx, bEpIdx, regVal); -} /* pcd_set_ep_tx_status */ +} /** * @brief sets the status for rx transfer (bits STAT_TX[1:0]) @@ -463,31 +442,27 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_status(USB_TypeDef * USBx * @retval None */ -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_status(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wState) -{ +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) - { + if((USB_EPRX_DTOG1 & wState)!= 0U) { regVal ^= USB_EPRX_DTOG1; } /* toggle second bit ? */ - if((USB_EPRX_DTOG2 & wState)!= 0U) - { + 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); -} /* pcd_set_ep_rx_status */ +} -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_status(USB_TypeDef * USBx, uint32_t bEpIdx) -{ +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); -} /* pcd_get_ep_rx_status */ +} /** @@ -496,16 +471,14 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_status(USB_TypeDef * * @param bEpIdx Endpoint Number. * @retval None */ -TU_ATTR_ALWAYS_INLINE static inline void pcd_rx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) -{ +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) -{ +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; @@ -518,21 +491,16 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_tx_dtog(USB_TypeDef * USBx, uint32 * @param bEpIdx Endpoint Number. * @retval None */ - -TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_rx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) -{ +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) - { + 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) -{ +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) - { + if((regVal & USB_EP_DTOG_TX) != 0) { pcd_tx_dtog(USBx,bEpIdx); } } @@ -543,17 +511,15 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_dtog(USB_TypeDef * USBx, * @param bEpIdx Endpoint Number. * @retval None */ - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_kind(USB_TypeDef * USBx, uint32_t 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) -{ + +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; From 27afa568445d193a075c6ca2b7bb1df76039d956 Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 31 Mar 2024 18:42:49 +0700 Subject: [PATCH 200/454] rename dcd_stm32_fsdev_pvt_st.h to simply dcd_stm32_fsdev.h --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 2 +- .../stm32_fsdev/{dcd_stm32_fsdev_pvt_st.h => dcd_stm32_fsdev.h} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/portable/st/stm32_fsdev/{dcd_stm32_fsdev_pvt_st.h => dcd_stm32_fsdev.h} (100%) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 9c37f1f98..5e54d0f56 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -109,7 +109,7 @@ #ifdef TUP_USBIP_FSDEV_STM32 // Undefine to reduce the dependence on HAL #undef USE_HAL_DRIVER - #include "portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h" + #include "portable/st/stm32_fsdev/dcd_stm32_fsdev.h" #endif /***************************************************** diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h similarity index 100% rename from src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h rename to src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h From fc54ad43b1ac89efa8853d69e836b16ddfe156fa Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 31 Mar 2024 21:53:12 +0700 Subject: [PATCH 201/454] move walkaround to dcd_ep_ctr_rx_handler(), increase cycle_count from 10 to 20 (40 cycle) --- .idea/runConfigurations/stlink.xml | 4 +- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 51 ++++++++++++------- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h | 10 ---- 3 files changed, 34 insertions(+), 31 deletions(-) diff --git a/.idea/runConfigurations/stlink.xml b/.idea/runConfigurations/stlink.xml index babb8b463..c82f37d59 100644 --- a/.idea/runConfigurations/stlink.xml +++ b/.idea/runConfigurations/stlink.xml @@ -1,6 +1,6 @@ - - + + diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 5e54d0f56..7bf726f3f 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -200,8 +200,7 @@ static bool dcd_read_packet_memory_ff(tu_fifo_t * ff, uint16_t src, uint16_t wNB // Inline helper //--------------------------------------------------------------------+ -TU_ATTR_ALWAYS_INLINE static inline xfer_ctl_t* xfer_ctl_ptr(uint32_t ep_addr) -{ +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 @@ -524,7 +523,7 @@ static void dcd_ep_ctr_tx_handler(uint32_t wIstr) xfer_ctl_t * xfer = xfer_ctl_ptr(ep_addr); if((xfer->total_len != xfer->queued_len)) /* TX not complete */ { - dcd_transmit_packet(xfer, EPindex); + dcd_transmit_packet(xfer, EPindex); } else /* TX Complete */ { @@ -533,10 +532,29 @@ static void dcd_ep_ctr_tx_handler(uint32_t wIstr) } // 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 wIstr) { + #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 40 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 2 cycle (1 cycle for sub, 1 cycle for compare/jump) + } + #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; @@ -545,8 +563,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) - { + if((wEPRegVal & USB_EP_CTR_RX) == 0U) { return; } @@ -633,26 +650,22 @@ 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... + // Always be prepared for a status packet... pcd_set_ep_rx_bufsize(USB, EPindex, CFG_TUD_ENDPOINT0_SIZE); pcd_clear_rx_ep_ctr(USB, EPindex); } } -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) - { - - if ((wIstr & USB_ISTR_DIR) == 0U) /* TX/IN */ - { + while (((wIstr = USB->ISTR) & USB_ISTR_CTR) != 0U) { + if ((wIstr & USB_ISTR_DIR) == 0U) { + /* TX/IN */ dcd_ep_ctr_tx_handler(wIstr); - } - else /* RX/OUT*/ - { + } else { + /* RX/OUT*/ dcd_ep_ctr_rx_handler(wIstr); } } diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h index 15de95d23..5de25765d 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h @@ -286,16 +286,6 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_cnt(USB_TypeDef * USB 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; - /* WA: few cycles for RX PMA descriptor to update, otherwise doesn't return the correct value. - Note: required for G0, U5, H5 etc. - This workaround is ported from stm32h5xx_hal_pcd.h and fixes the issue when calling this function fast enough. - Reproduced with GCC ast optimization(O2/O3) and stm32h573i_dk with an high frequency. - Observed on Windows 10 where tud_task() is scheduled by interrupt handler. - */ - volatile uint32_t count = 10; // defined as PCD_RX_PMA_CNT in stm32 hal_driver - while (count > 0U) { - count--; - } return (pma32[2*bEpIdx + 1] & 0x03FF0000) >> 16; #else __I uint16_t *regPtr = pcd_ep_rx_cnt_ptr(USBx, bEpIdx); From 943a2a6db335d98843b73246fcce9aead0d38886 Mon Sep 17 00:00:00 2001 From: Wojciech Klimek Date: Sun, 31 Mar 2024 23:11:49 +0200 Subject: [PATCH 202/454] Support for STM32H503 MCU - added support for STM32H503RB on H503RB-NUCLEO board - modified H5 family.c file to allow portability between H503 and H565/H573 - redefined USB_DRD_BASE to USB_DRD_FS_BASE if STM32H503xx is used --- .../boards/stm32h503nucleo/board.cmake | 8 + hw/bsp/stm32h5/boards/stm32h503nucleo/board.h | 142 ++++++++++++++++++ .../stm32h5/boards/stm32h503nucleo/board.mk | 7 + hw/bsp/stm32h5/boards/stm32h563nucleo/board.h | 18 ++- hw/bsp/stm32h5/boards/stm32h573i_dk/board.h | 18 ++- hw/bsp/stm32h5/family.c | 19 +-- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h | 5 + 7 files changed, 199 insertions(+), 18 deletions(-) create mode 100644 hw/bsp/stm32h5/boards/stm32h503nucleo/board.cmake create mode 100644 hw/bsp/stm32h5/boards/stm32h503nucleo/board.h create mode 100644 hw/bsp/stm32h5/boards/stm32h503nucleo/board.mk diff --git a/hw/bsp/stm32h5/boards/stm32h503nucleo/board.cmake b/hw/bsp/stm32h5/boards/stm32h503nucleo/board.cmake new file mode 100644 index 000000000..f0fb1d809 --- /dev/null +++ b/hw/bsp/stm32h5/boards/stm32h503nucleo/board.cmake @@ -0,0 +1,8 @@ +set(MCU_VARIANT stm32h503xx) +set(JLINK_DEVICE stm32h503rb) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + STM32H503xx + ) +endfunction() diff --git a/hw/bsp/stm32h5/boards/stm32h503nucleo/board.h b/hw/bsp/stm32h5/boards/stm32h503nucleo/board.h new file mode 100644 index 000000000..96c126ab8 --- /dev/null +++ b/hw/bsp/stm32h5/boards/stm32h503nucleo/board.h @@ -0,0 +1,142 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * 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. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +// LED +#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_STATE_ACTIVE 0 + +// UART Enable for STLink VCOM +#define UART_DEV USART3 +#define UART_CLK_EN __USART3_CLK_ENABLE +#define UART_GPIO_PORT GPIOA +#define UART_GPIO_AF GPIO_AF13_USART3 + +#define UART_TX_PIN GPIO_PIN_3 +#define UART_RX_PIN GPIO_PIN_4 + +// //--------------------------------------------------------------------+ +// // RCC Clock +// //--------------------------------------------------------------------+ +static inline void board_clock_init(void) +{ + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + + // Enable All GPIOs clocks + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + __HAL_RCC_GPIOH_CLK_ENABLE(); + + /** Configure the main internal regulator output voltage + */ + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0); + + while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {} + + /** Initializes the RCC Oscillators according to the specified parameters + * in the RCC_OscInitTypeDef structure. + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLL1_SOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = 12; + RCC_OscInitStruct.PLL.PLLN = 250; + RCC_OscInitStruct.PLL.PLLP = 2; + RCC_OscInitStruct.PLL.PLLQ = 2; + RCC_OscInitStruct.PLL.PLLR = 2; + RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1_VCIRANGE_1; + RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1_VCORANGE_WIDE; + RCC_OscInitStruct.PLL.PLLFRACN = 0; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) + { + Error_Handler(); + } + + /** 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; + + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK) + { + Error_Handler(); + } + + // Configure CRS clock source + __HAL_RCC_CRS_CLK_ENABLE(); + RCC_CRSInitTypeDef RCC_CRSInitStruct = {0}; + RCC_CRSInitStruct.Prescaler = RCC_CRS_SYNC_DIV1; + RCC_CRSInitStruct.Source = RCC_CRS_SYNC_SOURCE_USB; + RCC_CRSInitStruct.Polarity = RCC_CRS_SYNC_POLARITY_RISING; + RCC_CRSInitStruct.ReloadValue = __HAL_RCC_CRS_RELOADVALUE_CALCULATE(48000000, 1000); + RCC_CRSInitStruct.ErrorLimitValue = 34; + RCC_CRSInitStruct.HSI48CalibrationValue = 32; + HAL_RCCEx_CRSConfig(&RCC_CRSInitStruct); + + /* Select HSI48 as USB clock source */ + RCC_PeriphCLKInitTypeDef usb_clk = {0 }; + usb_clk.PeriphClockSelection = RCC_PERIPHCLK_USB; + usb_clk.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; + HAL_RCCEx_PeriphCLKConfig(&usb_clk); + + /* Peripheral clock enable */ + __HAL_RCC_USB_CLK_ENABLE(); +} + +static inline void board_enable_vdd_usb(void) +{ + // USB in STM32H503RB does not require enabling VDD +} + +#ifdef __cplusplus +} +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/stm32h5/boards/stm32h503nucleo/board.mk b/hw/bsp/stm32h5/boards/stm32h503nucleo/board.mk new file mode 100644 index 000000000..cf60098af --- /dev/null +++ b/hw/bsp/stm32h5/boards/stm32h503nucleo/board.mk @@ -0,0 +1,7 @@ +MCU_VARIANT = stm32h503xx + +CFLAGS += \ + -DSTM32H503xx + +# For flash-jlink target +JLINK_DEVICE = stm32h503rb diff --git a/hw/bsp/stm32h5/boards/stm32h563nucleo/board.h b/hw/bsp/stm32h5/boards/stm32h563nucleo/board.h index 8e849f5c8..ccbcbd8e2 100644 --- a/hw/bsp/stm32h5/boards/stm32h563nucleo/board.h +++ b/hw/bsp/stm32h5/boards/stm32h563nucleo/board.h @@ -54,10 +54,21 @@ extern "C" { //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ -static inline void SystemClock_Config(void) { +static inline void board_clock_init(void) +{ RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + // Enable All GPIOs clocks + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + __HAL_RCC_GPIOE_CLK_ENABLE(); + __HAL_RCC_GPIOG_CLK_ENABLE(); + __HAL_RCC_GPIOH_CLK_ENABLE(); + __HAL_RCC_GPIOI_CLK_ENABLE(); + /** Configure the main internal regulator output voltage */ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0); @@ -122,6 +133,11 @@ static inline void SystemClock_Config(void) { __HAL_RCC_USB_CLK_ENABLE(); } +static inline void board_enable_vdd_usb(void) +{ + /* Enable VDDUSB to power on USB peripheral */ + HAL_PWREx_EnableVddUSB(); +} #ifdef __cplusplus } #endif diff --git a/hw/bsp/stm32h5/boards/stm32h573i_dk/board.h b/hw/bsp/stm32h5/boards/stm32h573i_dk/board.h index 674cf8e2a..87bf2ac1a 100644 --- a/hw/bsp/stm32h5/boards/stm32h573i_dk/board.h +++ b/hw/bsp/stm32h5/boards/stm32h573i_dk/board.h @@ -54,10 +54,20 @@ extern "C" { //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ -static inline void SystemClock_Config(void) { +static inline void board_clock_init(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + // Enable All GPIOs clocks + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + __HAL_RCC_GPIOE_CLK_ENABLE(); + __HAL_RCC_GPIOG_CLK_ENABLE(); + __HAL_RCC_GPIOH_CLK_ENABLE(); + __HAL_RCC_GPIOI_CLK_ENABLE(); + /** Configure the main internal regulator output voltage */ HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1); @@ -108,6 +118,12 @@ static inline void SystemClock_Config(void) { __HAL_RCC_USB_CLK_ENABLE(); } +static inline void board_enable_vdd_usb(void) +{ + /* Enable VDDUSB to power on USB peripheral */ + HAL_PWREx_EnableVddUSB(); +} + #ifdef __cplusplus } #endif diff --git a/hw/bsp/stm32h5/family.c b/hw/bsp/stm32h5/family.c index ed1389a12..0ff09a259 100644 --- a/hw/bsp/stm32h5/family.c +++ b/hw/bsp/stm32h5/family.c @@ -59,23 +59,10 @@ UART_HandleTypeDef UartHandle; void board_init(void) { HAL_Init(); // required for HAL_RCC_Osc TODO check with freeRTOS - SystemClock_Config(); // implemented in board.h + board_clock_init(); // implemented in board.h SystemCoreClockUpdate(); - // Enable All GPIOs clocks - __HAL_RCC_GPIOA_CLK_ENABLE(); - __HAL_RCC_GPIOB_CLK_ENABLE(); - __HAL_RCC_GPIOC_CLK_ENABLE(); - __HAL_RCC_GPIOD_CLK_ENABLE(); - __HAL_RCC_GPIOE_CLK_ENABLE(); - __HAL_RCC_GPIOG_CLK_ENABLE(); - __HAL_RCC_GPIOH_CLK_ENABLE(); - __HAL_RCC_GPIOI_CLK_ENABLE(); - - //__HAL_RCC_SYSCFG_CLK_ENABLE(); - //__HAL_RCC_PWR_CLK_ENABLE(); - - UART_CLK_EN(); + UART_CLK_EN(); #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer @@ -141,7 +128,7 @@ void board_init(void) { __HAL_RCC_USB_CLK_ENABLE(); /* Enable VDDUSB */ - HAL_PWREx_EnableVddUSB(); + board_enable_vdd_usb(); } //--------------------------------------------------------------------+ diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h index 5de25765d..8cedee5d1 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h @@ -115,6 +115,11 @@ #elif CFG_TUSB_MCU == OPT_MCU_STM32H5 #include "stm32h5xx.h" #define FSDEV_BUS_32BIT + + #ifdef STM32H503xx + #define USB_DRD_BASE USB_DRD_FS_BASE + #endif + #define FSDEV_PMA_SIZE (2048u) #undef USB_PMAADDR #define USB_PMAADDR USB_DRD_PMAADDR From 057278c0c6c159880e11f9b16de5735d8fc821ce Mon Sep 17 00:00:00 2001 From: Wojciech Klimek Date: Mon, 1 Apr 2024 14:51:46 +0200 Subject: [PATCH 203/454] Support for STM32H503 MCU - review changes Implemented changes suggested in the review: - restored original name of SystemClock_Config() function - some GPIO clocks are only enabled if macros are defined - moved GPIO clocks init back to family.c --- hw/bsp/stm32h5/boards/stm32h503nucleo/board.h | 15 ++++----------- hw/bsp/stm32h5/boards/stm32h563nucleo/board.h | 12 +----------- hw/bsp/stm32h5/boards/stm32h573i_dk/board.h | 12 +----------- hw/bsp/stm32h5/family.c | 19 ++++++++++++++++++- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h | 2 +- 5 files changed, 25 insertions(+), 35 deletions(-) diff --git a/hw/bsp/stm32h5/boards/stm32h503nucleo/board.h b/hw/bsp/stm32h5/boards/stm32h503nucleo/board.h index 96c126ab8..0651b2694 100644 --- a/hw/bsp/stm32h5/boards/stm32h503nucleo/board.h +++ b/hw/bsp/stm32h5/boards/stm32h503nucleo/board.h @@ -51,21 +51,14 @@ extern "C" { #define UART_TX_PIN GPIO_PIN_3 #define UART_RX_PIN GPIO_PIN_4 -// //--------------------------------------------------------------------+ -// // RCC Clock -// //--------------------------------------------------------------------+ -static inline void board_clock_init(void) +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ +static inline void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; - // Enable All GPIOs clocks - __HAL_RCC_GPIOA_CLK_ENABLE(); - __HAL_RCC_GPIOB_CLK_ENABLE(); - __HAL_RCC_GPIOC_CLK_ENABLE(); - __HAL_RCC_GPIOD_CLK_ENABLE(); - __HAL_RCC_GPIOH_CLK_ENABLE(); - /** Configure the main internal regulator output voltage */ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0); diff --git a/hw/bsp/stm32h5/boards/stm32h563nucleo/board.h b/hw/bsp/stm32h5/boards/stm32h563nucleo/board.h index ccbcbd8e2..df249242a 100644 --- a/hw/bsp/stm32h5/boards/stm32h563nucleo/board.h +++ b/hw/bsp/stm32h5/boards/stm32h563nucleo/board.h @@ -54,21 +54,11 @@ extern "C" { //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ -static inline void board_clock_init(void) +static inline void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; - // Enable All GPIOs clocks - __HAL_RCC_GPIOA_CLK_ENABLE(); - __HAL_RCC_GPIOB_CLK_ENABLE(); - __HAL_RCC_GPIOC_CLK_ENABLE(); - __HAL_RCC_GPIOD_CLK_ENABLE(); - __HAL_RCC_GPIOE_CLK_ENABLE(); - __HAL_RCC_GPIOG_CLK_ENABLE(); - __HAL_RCC_GPIOH_CLK_ENABLE(); - __HAL_RCC_GPIOI_CLK_ENABLE(); - /** Configure the main internal regulator output voltage */ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0); diff --git a/hw/bsp/stm32h5/boards/stm32h573i_dk/board.h b/hw/bsp/stm32h5/boards/stm32h573i_dk/board.h index 87bf2ac1a..c58de13ee 100644 --- a/hw/bsp/stm32h5/boards/stm32h573i_dk/board.h +++ b/hw/bsp/stm32h5/boards/stm32h573i_dk/board.h @@ -54,20 +54,10 @@ extern "C" { //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ -static inline void board_clock_init(void) { +static inline void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; - // Enable All GPIOs clocks - __HAL_RCC_GPIOA_CLK_ENABLE(); - __HAL_RCC_GPIOB_CLK_ENABLE(); - __HAL_RCC_GPIOC_CLK_ENABLE(); - __HAL_RCC_GPIOD_CLK_ENABLE(); - __HAL_RCC_GPIOE_CLK_ENABLE(); - __HAL_RCC_GPIOG_CLK_ENABLE(); - __HAL_RCC_GPIOH_CLK_ENABLE(); - __HAL_RCC_GPIOI_CLK_ENABLE(); - /** Configure the main internal regulator output voltage */ HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1); diff --git a/hw/bsp/stm32h5/family.c b/hw/bsp/stm32h5/family.c index 0ff09a259..e4a9666b7 100644 --- a/hw/bsp/stm32h5/family.c +++ b/hw/bsp/stm32h5/family.c @@ -59,9 +59,26 @@ UART_HandleTypeDef UartHandle; void board_init(void) { HAL_Init(); // required for HAL_RCC_Osc TODO check with freeRTOS - board_clock_init(); // implemented in board.h + SystemClock_Config(); // implemented in board.h SystemCoreClockUpdate(); + // Enable All GPIOs clocks + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + __HAL_RCC_GPIOH_CLK_ENABLE(); + + #ifdef __HAL_RCC_GPIOE_CLK_ENABLE + __HAL_RCC_GPIOE_CLK_ENABLE(); + #endif + #ifdef __HAL_RCC_GPIOG_CLK_ENABLE + __HAL_RCC_GPIOE_CLK_ENABLE(); + #endif + #ifdef __HAL_RCC_GPIOI_CLK_ENABLE + __HAL_RCC_GPIOE_CLK_ENABLE(); + #endif + UART_CLK_EN(); #if CFG_TUSB_OS == OPT_OS_NONE diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h index 8cedee5d1..946ad2c7c 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h @@ -116,7 +116,7 @@ #include "stm32h5xx.h" #define FSDEV_BUS_32BIT - #ifdef STM32H503xx + #if !defined(USB_DRD_BASE) && defined(USB_DRD_FS_BASE) #define USB_DRD_BASE USB_DRD_FS_BASE #endif From 4fcfb30f8130f50053f58b523327089d0132d4b3 Mon Sep 17 00:00:00 2001 From: Wojciech Klimek Date: Mon, 1 Apr 2024 15:20:57 +0200 Subject: [PATCH 204/454] Fixed trailing whitespace in family.c --- hw/bsp/stm32h5/family.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/bsp/stm32h5/family.c b/hw/bsp/stm32h5/family.c index e4a9666b7..4eb846933 100644 --- a/hw/bsp/stm32h5/family.c +++ b/hw/bsp/stm32h5/family.c @@ -68,7 +68,7 @@ void board_init(void) { __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOH_CLK_ENABLE(); - + #ifdef __HAL_RCC_GPIOE_CLK_ENABLE __HAL_RCC_GPIOE_CLK_ENABLE(); #endif From 05f9cab1916195ceb55d73efa56d226b2451f5d1 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Mon, 1 Apr 2024 19:48:45 +0200 Subject: [PATCH 205/454] UAC2: refactor interrupt endpoint support. --- src/class/audio/audio.h | 25 ++++++++ src/class/audio/audio_device.c | 114 ++++++++++++++------------------- src/class/audio/audio_device.h | 51 ++------------- src/device/usbd.h | 11 +++- 4 files changed, 88 insertions(+), 113 deletions(-) diff --git a/src/class/audio/audio.h b/src/class/audio/audio.h index 70d431282..d6f3e22e2 100644 --- a/src/class/audio/audio.h +++ b/src/class/audio/audio.h @@ -924,6 +924,31 @@ typedef struct TU_ATTR_PACKED { } subrange[numSubRanges]; \ } +// 6.1 Interrupt Data Message Format +typedef struct TU_ATTR_PACKED +{ + uint8_t bInfo; + uint8_t bAttribute; + union + { + uint16_t wValue; + struct + { + uint8_t wValue_cn_or_mcn; + uint8_t wValue_cs; + }; + }; + union + { + uint16_t wIndex; + struct + { + uint8_t wIndex_ep_or_int; + uint8_t wIndex_entity_id; + }; + }; +} audio_interrupt_data_t; + /** @} */ #ifdef __cplusplus diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index f4e7de0c8..93e995c56 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -301,8 +301,8 @@ typedef struct #endif -#if CFG_TUD_AUDIO_INT_EPSIZE_IN - uint8_t ep_int; // Audio control interrupt EP. +#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP + uint8_t ep_int; // Audio control interrupt EP. #endif /*------------- From this point, data is not cleared by bus reset -------------*/ @@ -358,8 +358,8 @@ typedef struct #endif // Audio control interrupt buffer - no FIFO - 6 Bytes according to UAC 2 specification (p. 74) -#if CFG_TUD_AUDIO_INT_EPSIZE_IN - CFG_TUSB_MEM_ALIGN uint8_t ep_int_buf[CFG_TUD_AUDIO_INT_EP_IN_SW_BUFFER_SIZE]; +#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 @@ -826,26 +826,29 @@ tu_fifo_t* tud_audio_n_get_tx_support_ff(uint8_t func_id, uint8_t ff_idx) #if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP - // If no interrupt transmit is pending bytes get written into buffer and a transmit is scheduled - once transmit completed tud_audio_int_done_cb() is called in inform user -uint16_t tud_audio_int_n_write(uint8_t func_id, uint8_t const* buffer, uint16_t len) +bool tud_audio_int_n_write(uint8_t func_id, const audio_interrupt_data_t * data) { - TU_VERIFY(_audiod_fct[func_id].ep_int != 0); - TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL); + TU_VERIFY(_audiod_fct[func_id].ep_int != 0); + // We write directly into the EP's buffer - abort if previous transfer not complete - TU_VERIFY(!usbd_edpt_busy(_audiod_fct[func_id].rhport, _audiod_fct[func_id].ep_int)); + TU_VERIFY(usbd_edpt_claim(_audiod_fct[func_id].rhport, _audiod_fct[func_id].ep_int)); // Check length - TU_VERIFY(tu_memcpy_s(_audiod_fct[func_id].ep_int_buf, CFG_TUD_AUDIO_INT_EP_IN_SW_BUFFER_SIZE, buffer, len)==0); - - // Schedule transmit - TU_VERIFY(usbd_edpt_xfer(_audiod_fct[func_id].rhport, _audiod_fct[func_id].ep_int, _audiod_fct[func_id].ep_int_buf, len)); + if (tu_memcpy_s(_audiod_fct[func_id].ep_int_buf, sizeof(_audiod_fct[func_id].ep_int_buf), data, sizeof(audio_interrupt_data_t)) == 0) + { + // Schedule transmit + TU_ASSERT(usbd_edpt_xfer(_audiod_fct[func_id].rhport, _audiod_fct[func_id].ep_int, _audiod_fct[func_id].ep_int_buf, sizeof(_audiod_fct[func_id].ep_int_buf)), 0); + } else + { + // Release endpoint since we don't make any transfer + usbd_edpt_release(_audiod_fct[func_id].rhport, _audiod_fct[func_id].ep_int); + } return true; } - #endif // This function is called once a transmit of an audio packet was successfully completed. Here, we encode samples and place it in IN EP's buffer for next transmission. @@ -1091,48 +1094,6 @@ static inline bool audiod_fb_send(uint8_t rhport, audiod_function_t *audio) } #endif -#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP -static bool set_int_number(audiod_function_t *audio) -{ - - uint8_t const *p_desc = audio->p_desc; - // Get pointer at end - uint8_t const *p_desc_end = audio->p_desc + audio->desc_length - TUD_AUDIO_DESC_IAD_LEN; - - - bool found = false; - while (!found && p_desc < p_desc_end) - { - // For each interface/alternate - if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE) - { - uint8_t foundEPs = 0, nEps = ((tusb_desc_interface_t const * )p_desc)->bNumEndpoints; - while (!found && foundEPs < nEps && p_desc < p_desc_end) - { - // For each endpoint - if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) - { - tusb_desc_endpoint_t const* desc_ep = (tusb_desc_endpoint_t const *) p_desc; - uint8_t const ep_addr = desc_ep->bEndpointAddress; - // If endpoint is input-direction and interrupt-type - if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN && desc_ep->bmAttributes.xfer == 0x03) // Check if usage is interrupt EP - { - // Store endpoint number and open endpoint - audio->ep_int = ep_addr; - TU_ASSERT(usbd_edpt_open(audio->rhport, desc_ep)); - found = true; - } - foundEPs += 1; - } - p_desc = tu_desc_next(p_desc); - } - } - p_desc = tu_desc_next(p_desc); - } - return found; -} -#endif - //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ @@ -1492,10 +1453,11 @@ uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin // Verify version is correct - this check can be omitted TU_VERIFY(itf_desc->bInterfaceProtocol == AUDIO_INT_PROTOCOL_CODE_V2); - // Verify interrupt control EP is enabled if demanded by descriptor - this should be best some static check however - this check can be omitted - if (itf_desc->bNumEndpoints == 1) // 0 or 1 EPs are allowed + // Verify interrupt control EP is enabled if demanded by descriptor + TU_ASSERT(itf_desc->bNumEndpoints <= 1); // 0 or 1 EPs are allowed + if (itf_desc->bNumEndpoints == 1) { - TU_VERIFY(CFG_TUD_AUDIO_INT_EPSIZE_IN > 0); + TU_ASSERT(CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP); } // Alternate setting MUST be zero - this check can be omitted @@ -1639,6 +1601,31 @@ uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin } #endif // CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL +#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP + { + 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; + // Condition modified from p_desc < p_desc_end to prevent gcc>=12 strict-overflow warning + while (p_desc_end - p_desc > 0) + { + // For each endpoint + if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) + { + tusb_desc_endpoint_t const* desc_ep = (tusb_desc_endpoint_t const *) p_desc; + uint8_t const ep_addr = desc_ep->bEndpointAddress; + // If endpoint is input-direction and interrupt-type + if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN && desc_ep->bmAttributes.xfer == TUSB_XFER_INTERRUPT) + { + // Store endpoint number and open endpoint + _audiod_fct[i].ep_int = ep_addr; + TU_ASSERT(usbd_edpt_open(_audiod_fct[i].rhport, desc_ep)); + } + } + p_desc = tu_desc_next(p_desc); + } + } +#endif + break; } } @@ -1649,10 +1636,6 @@ uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin // This is all we need so far - the EPs are setup by a later set_interface request (as per UAC2 specification) uint16_t drv_len = _audiod_fct[i].desc_length - TUD_AUDIO_DESC_IAD_LEN; // - TUD_AUDIO_DESC_IAD_LEN since tinyUSB already handles the IAD descriptor -#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP - TU_ASSERT(set_int_number(&_audiod_fct[i])); -#endif - return drv_len; } @@ -2169,7 +2152,7 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 { audiod_function_t* audio = &_audiod_fct[func_id]; -#if CFG_TUD_AUDIO_INT_EPSIZE_IN +#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP // Data transmission of control interrupt finished if (audio->ep_int == ep_addr) @@ -2181,7 +2164,8 @@ 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) TU_VERIFY(tud_audio_int_done_cb(rhport, (uint16_t) xferred_bytes)); + if (tud_audio_int_done_cb) tud_audio_int_done_cb(rhport); + return true; } #endif diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index 70bbd7ff6..040a760d6 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -198,21 +198,7 @@ // Enable/disable interrupt EP (required for notifying host of control changes) #ifndef CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP -#define CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP 0 // Feedback - 0 or 1 -#endif - -// Audio interrupt control EP size - disabled if 0 -#ifndef CFG_TUD_AUDIO_INT_EPSIZE_IN -// Audio interrupt control - if required - 6 Bytes according to UAC 2 specification (p. 74) -#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP -#define CFG_TUD_AUDIO_INT_EPSIZE_IN 6 -#else -#define CFG_TUD_AUDIO_INT_EPSIZE_IN 0 -#endif -#endif - -#ifndef CFG_TUD_AUDIO_INT_EP_IN_SW_BUFFER_SIZE -#define CFG_TUD_AUDIO_INT_EP_IN_SW_BUFFER_SIZE 6 // Buffer size of audio control interrupt EP - 6 Bytes according to UAC 2 specification (p. 74) +#define CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP 0 // Feedback - 0 or 1 #endif // Use software encoding/decoding @@ -404,7 +390,7 @@ tu_fifo_t* tud_audio_n_get_tx_support_ff (uint8_t func_id, uint8_t ff_i #endif #if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP -uint16_t tud_audio_int_n_write (uint8_t func_id, uint8_t const* buffer, uint16_t len); +bool tud_audio_int_n_write (uint8_t func_id, const audio_interrupt_data_t * data); #endif @@ -448,7 +434,7 @@ static inline tu_fifo_t* tud_audio_get_tx_support_ff (uint8_t ff_idx); // INT CTR API #if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP -static inline uint16_t tud_audio_int_write (uint8_t const* buffer, uint16_t len); +static inline bool tud_audio_int_write (const audio_interrupt_data_t * data); #endif // Buffer control EP data and schedule a transmit @@ -548,32 +534,7 @@ TU_ATTR_WEAK TU_ATTR_FAST_FUNC void tud_audio_feedback_interval_isr(uint8_t func #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP #if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP -// UAC2 §6.1 "interrupt data message" -typedef struct TU_ATTR_PACKED -{ - uint8_t bInfo; - uint8_t bAttribute; - union TU_ATTR_PACKED - { - uint16_t wValue; - struct TU_ATTR_PACKED - { - uint8_t wValue_cn_or_mcn; - uint8_t wValue_cs; - }; - }; - union TU_ATTR_PACKED - { - uint16_t wIndex; - struct TU_ATTR_PACKED - { - uint8_t wIndex_ep_or_int; - uint8_t wIndex_entity_id; - }; - }; -} audio_status_update_t; - -TU_ATTR_WEAK bool tud_audio_int_done_cb(uint8_t rhport, uint16_t n_bytes_copied); +TU_ATTR_WEAK void tud_audio_int_done_cb(uint8_t rhport); #endif // Invoked when audio set interface request received @@ -705,9 +666,9 @@ static inline tu_fifo_t* tud_audio_get_tx_support_ff(uint8_t ff_idx) #endif #if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP -static inline uint16_t tud_audio_int_write(uint8_t const* buffer, uint16_t len) +static inline bool tud_audio_int_write(const audio_interrupt_data_t * data) { - return tud_audio_int_n_write(0, buffer, len); + return tud_audio_int_n_write(0, data); } #endif diff --git a/src/device/usbd.h b/src/device/usbd.h index cf500143a..2e3987b99 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -393,6 +393,11 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb // For more channels, add definitions here +/* Standard AC Interrupt Endpoint Descriptor(4.8.2.1) */ +#define TUD_AUDIO_DESC_STD_AC_INT_EP_LEN 7 +#define TUD_AUDIO_DESC_STD_AC_INT_EP(_ep, _interval) \ + TUD_AUDIO_DESC_STD_AC_INT_EP_LEN, TUSB_DESC_ENDPOINT, _ep, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(6), _interval + /* Standard AS Interface Descriptor(4.9.1) */ #define TUD_AUDIO_DESC_STD_AS_INT_LEN 9 #define TUD_AUDIO_DESC_STD_AS_INT(_itfnum, _altset, _nEPs, _stridx) \ @@ -468,7 +473,7 @@ 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*/ _epin, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01),\ + TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_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_UNDEFINED, /*_lockdelay*/ 0x0000) @@ -517,7 +522,7 @@ 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*/ _epin, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01),\ + TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_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_UNDEFINED, /*_lockdelay*/ 0x0000) @@ -565,7 +570,7 @@ 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) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | 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*/ _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_UNDEFINED, /*_lockdelay*/ 0x0000),\ /* Standard AS Isochronous Feedback Endpoint Descriptor(4.10.2.1) */\ From 7ca988018ee057a66ab7d5635069fbc695182d2d Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Mon, 1 Apr 2024 19:50:52 +0200 Subject: [PATCH 206/454] UAC2: fix mounted condition. --- src/class/audio/audio_device.c | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 93e995c56..9a361419b 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -305,6 +305,8 @@ typedef struct uint8_t ep_int; // Audio control interrupt EP. #endif + bool mounted; // Device opened + /*------------- From this point, data is not cleared by bus reset -------------*/ uint16_t desc_length; // Length of audio function descriptor @@ -486,23 +488,7 @@ bool tud_audio_n_mounted(uint8_t func_id) TU_VERIFY(func_id < CFG_TUD_AUDIO); audiod_function_t* audio = &_audiod_fct[func_id]; -#if CFG_TUD_AUDIO_ENABLE_EP_OUT - if (audio->ep_out == 0) return false; -#endif - -#if CFG_TUD_AUDIO_ENABLE_EP_IN - if (audio->ep_in == 0) return false; -#endif - -#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP - if (audio->ep_int == 0) return false; -#endif - -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP - if (audio->ep_fb == 0) return false; -#endif - - return true; + return audio->mounted; } //--------------------------------------------------------------------+ @@ -1626,6 +1612,7 @@ uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin } #endif + _audiod_fct[i].mounted = true; break; } } From 6cf27986b67996290c12f102d62c1a38e66e08d6 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Mon, 1 Apr 2024 19:55:51 +0200 Subject: [PATCH 207/454] UAC2: add interrupt volume control to uac2_headset example. --- examples/device/uac2_headset/src/main.c | 41 +++++++++++++++++++ .../device/uac2_headset/src/tusb_config.h | 3 ++ .../device/uac2_headset/src/usb_descriptors.c | 7 +++- .../device/uac2_headset/src/usb_descriptors.h | 15 ++++--- 4 files changed, 59 insertions(+), 7 deletions(-) diff --git a/examples/device/uac2_headset/src/main.c b/examples/device/uac2_headset/src/main.c index 0ab72b2f3..35b7ac94b 100644 --- a/examples/device/uac2_headset/src/main.c +++ b/examples/device/uac2_headset/src/main.c @@ -96,6 +96,7 @@ uint8_t current_resolution; void led_blinking_task(void); void audio_task(void); +void audio_control_task(void); /*------------- MAIN -------------*/ int main(void) @@ -115,6 +116,7 @@ int main(void) { tud_task(); // TinyUSB device task audio_task(); + audio_control_task(); led_blinking_task(); } } @@ -428,6 +430,45 @@ void audio_task(void) } } +void audio_control_task(void) +{ + // Press on-board button to control volume + // Open host volume control, volume should switch between 10% and 100% + + // Poll every 50ms + const uint32_t interval_ms = 50; + static uint32_t start_ms = 0; + static uint32_t btn_prev = 0; + + if ( board_millis() - start_ms < interval_ms) return; // not enough time + start_ms += interval_ms; + + uint32_t btn = board_button_read(); + + if (!btn_prev && btn) + { + // Adjust volume between 0dB (100%) and -30dB (10%) + for (int i = 0; i < CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1; i++) + { + volume[i] = volume[i] == 0 ? -VOLUME_CTRL_30_DB : 0; + } + + // 6.1 Interrupt Data Message + const audio_interrupt_data_t data = { + .bInfo = 0, // Class-specific interrupt, originated from an interface + .bAttribute = AUDIO_CS_REQ_CUR, // Caused by current settings + .wValue_cn_or_mcn = 0, // CH0: master volume + .wValue_cs = AUDIO_FU_CTRL_VOLUME, // Volume change + .wIndex_ep_or_int = 0, // From the interface itself + .wIndex_entity_id = UAC2_ENTITY_SPK_FEATURE_UNIT, // From feature unit + }; + + tud_audio_int_write(&data); + } + + btn_prev = btn; +} + //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ diff --git a/examples/device/uac2_headset/src/tusb_config.h b/examples/device/uac2_headset/src/tusb_config.h index b770483dc..4b08fa676 100644 --- a/examples/device/uac2_headset/src/tusb_config.h +++ b/examples/device/uac2_headset/src/tusb_config.h @@ -105,6 +105,9 @@ extern "C" { // AUDIO CLASS DRIVER CONFIGURATION //-------------------------------------------------------------------- +// Allow volume controlled by on-baord button +#define CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP 1 + #define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO_HEADSET_STEREO_DESC_LEN // How many formats are used, need to adjust USB descriptor if changed diff --git a/examples/device/uac2_headset/src/usb_descriptors.c b/examples/device/uac2_headset/src/usb_descriptors.c index 6d1e6a23f..ff4dc2acc 100644 --- a/examples/device/uac2_headset/src/usb_descriptors.c +++ b/examples/device/uac2_headset/src/usb_descriptors.c @@ -82,27 +82,32 @@ uint8_t const * tud_descriptor_device_cb(void) // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... #define EPNUM_AUDIO_IN 0x03 #define EPNUM_AUDIO_OUT 0x03 + #define EPNUM_AUDIO_INT 0x01 #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 #else #define EPNUM_AUDIO_IN 0x01 #define EPNUM_AUDIO_OUT 0x01 + #define EPNUM_AUDIO_INT 0x02 #endif uint8_t const desc_configuration[] = @@ -111,7 +116,7 @@ uint8_t const desc_configuration[] = 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_HEADSET_STEREO_DESCRIPTOR(2, EPNUM_AUDIO_OUT, EPNUM_AUDIO_IN | 0x80) + TUD_AUDIO_HEADSET_STEREO_DESCRIPTOR(2, EPNUM_AUDIO_OUT, EPNUM_AUDIO_IN | 0x80, EPNUM_AUDIO_INT | 0x80) }; // Invoked when received GET CONFIGURATION DESCRIPTOR diff --git a/examples/device/uac2_headset/src/usb_descriptors.h b/examples/device/uac2_headset/src/usb_descriptors.h index d7e170162..da0da83e8 100644 --- a/examples/device/uac2_headset/src/usb_descriptors.h +++ b/examples/device/uac2_headset/src/usb_descriptors.h @@ -55,6 +55,7 @@ enum + TUD_AUDIO_DESC_OUTPUT_TERM_LEN\ + TUD_AUDIO_DESC_INPUT_TERM_LEN\ + TUD_AUDIO_DESC_OUTPUT_TERM_LEN\ + + TUD_AUDIO_DESC_STD_AC_INT_EP_LEN\ /* Interface 1, Alternate 0 */\ + TUD_AUDIO_DESC_STD_AS_INT_LEN\ /* Interface 1, Alternate 1 */\ @@ -84,11 +85,11 @@ enum + TUD_AUDIO_DESC_STD_AS_ISO_EP_LEN\ + TUD_AUDIO_DESC_CS_AS_ISO_EP_LEN) -#define TUD_AUDIO_HEADSET_STEREO_DESCRIPTOR(_stridx, _epout, _epin) \ +#define TUD_AUDIO_HEADSET_STEREO_DESCRIPTOR(_stridx, _epout, _epin, _epint) \ /* Standard Interface Association Descriptor (IAD) */\ TUD_AUDIO_DESC_IAD(/*_firstitf*/ ITF_NUM_AUDIO_CONTROL, /*_nitfs*/ ITF_NUM_TOTAL, /*_stridx*/ 0x00),\ /* Standard AC Interface Descriptor(4.7.1) */\ - TUD_AUDIO_DESC_STD_AC(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\ + TUD_AUDIO_DESC_STD_AC(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_nEPs*/ 0x01, /*_stridx*/ _stridx),\ /* Class-Specific AC Interface Header Descriptor(4.7.2) */\ TUD_AUDIO_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO_FUNC_HEADSET, /*_totallen*/ TUD_AUDIO_DESC_CLK_SRC_LEN+TUD_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL_LEN+TUD_AUDIO_DESC_INPUT_TERM_LEN+TUD_AUDIO_DESC_OUTPUT_TERM_LEN+TUD_AUDIO_DESC_INPUT_TERM_LEN+TUD_AUDIO_DESC_OUTPUT_TERM_LEN, /*_ctrl*/ AUDIO_CS_AS_INTERFACE_CTRL_LATENCY_POS),\ /* Clock Source Descriptor(4.7.2.1) */\ @@ -103,6 +104,8 @@ enum TUD_AUDIO_DESC_INPUT_TERM(/*_termid*/ UAC2_ENTITY_MIC_INPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_IN_GENERIC_MIC, /*_assocTerm*/ 0x00, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_nchannelslogical*/ 0x01, /*_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*/ UAC2_ENTITY_MIC_OUTPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, /*_srcid*/ UAC2_ENTITY_MIC_INPUT_TERMINAL, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\ + /* Standard AC Interrupt Endpoint Descriptor(4.8.2.1) */\ + TUD_AUDIO_DESC_STD_AC_INT_EP(/*_ep*/ _epint, /*_interval*/ 0x01), \ /* 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)(ITF_NUM_AUDIO_STREAMING_SPK), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x05),\ @@ -114,7 +117,7 @@ enum /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ TUD_AUDIO_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_RX),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ADAPTIVE | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX), /*_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_ADAPTIVE | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX), /*_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),\ /* Interface 1, Alternate 2 - alternate interface for data streaming */\ @@ -124,7 +127,7 @@ enum /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ TUD_AUDIO_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_RESOLUTION_RX),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ADAPTIVE | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX), /*_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_ADAPTIVE | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX), /*_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 Interface Descriptor(4.9.1) */\ @@ -138,7 +141,7 @@ enum /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ TUD_AUDIO_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_TX),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX), /*_interval*/ 0x01),\ + TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX), /*_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),\ /* Interface 2, Alternate 2 - alternate interface for data streaming */\ @@ -148,7 +151,7 @@ enum /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ TUD_AUDIO_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_RESOLUTION_TX),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX), /*_interval*/ 0x01),\ + TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX), /*_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) From 4b993708c966977de082a2087865163df7186b2c Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Mon, 1 Apr 2024 21:30:36 +0200 Subject: [PATCH 208/454] Minor format --- hw/bsp/stm32h5/boards/stm32h503nucleo/board.h | 17 ++++------------- hw/bsp/stm32h5/boards/stm32h563nucleo/board.h | 6 ++---- hw/bsp/stm32h5/boards/stm32h573i_dk/board.h | 3 +-- 3 files changed, 7 insertions(+), 19 deletions(-) diff --git a/hw/bsp/stm32h5/boards/stm32h503nucleo/board.h b/hw/bsp/stm32h5/boards/stm32h503nucleo/board.h index 0651b2694..531f00425 100644 --- a/hw/bsp/stm32h5/boards/stm32h503nucleo/board.h +++ b/hw/bsp/stm32h5/boards/stm32h503nucleo/board.h @@ -54,8 +54,7 @@ extern "C" { //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ -static inline void SystemClock_Config(void) -{ +static inline void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; @@ -81,10 +80,7 @@ static inline void SystemClock_Config(void) RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1_VCIRANGE_1; RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1_VCORANGE_WIDE; RCC_OscInitStruct.PLL.PLLFRACN = 0; - if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) - { - Error_Handler(); - } + HAL_RCC_OscConfig(&RCC_OscInitStruct); /** Initializes the CPU, AHB and APB buses clocks */ @@ -96,11 +92,7 @@ static inline void SystemClock_Config(void) RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB3CLKDivider = RCC_HCLK_DIV1; - - if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK) - { - Error_Handler(); - } + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5); // Configure CRS clock source __HAL_RCC_CRS_CLK_ENABLE(); @@ -123,8 +115,7 @@ static inline void SystemClock_Config(void) __HAL_RCC_USB_CLK_ENABLE(); } -static inline void board_enable_vdd_usb(void) -{ +static inline void board_enable_vdd_usb(void) { // USB in STM32H503RB does not require enabling VDD } diff --git a/hw/bsp/stm32h5/boards/stm32h563nucleo/board.h b/hw/bsp/stm32h5/boards/stm32h563nucleo/board.h index df249242a..13eaed6aa 100644 --- a/hw/bsp/stm32h5/boards/stm32h563nucleo/board.h +++ b/hw/bsp/stm32h5/boards/stm32h563nucleo/board.h @@ -54,8 +54,7 @@ extern "C" { //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ -static inline void SystemClock_Config(void) -{ +static inline void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; @@ -123,8 +122,7 @@ static inline void SystemClock_Config(void) __HAL_RCC_USB_CLK_ENABLE(); } -static inline void board_enable_vdd_usb(void) -{ +static inline void board_enable_vdd_usb(void) { /* Enable VDDUSB to power on USB peripheral */ HAL_PWREx_EnableVddUSB(); } diff --git a/hw/bsp/stm32h5/boards/stm32h573i_dk/board.h b/hw/bsp/stm32h5/boards/stm32h573i_dk/board.h index c58de13ee..b98939cc1 100644 --- a/hw/bsp/stm32h5/boards/stm32h573i_dk/board.h +++ b/hw/bsp/stm32h5/boards/stm32h573i_dk/board.h @@ -108,8 +108,7 @@ static inline void SystemClock_Config(void) { __HAL_RCC_USB_CLK_ENABLE(); } -static inline void board_enable_vdd_usb(void) -{ +static inline void board_enable_vdd_usb(void) { /* Enable VDDUSB to power on USB peripheral */ HAL_PWREx_EnableVddUSB(); } From bd2210b812cca0f56fc54ab9ebe3e48482baa653 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 2 Apr 2024 12:36:00 +0700 Subject: [PATCH 209/454] always limit number of NAK per endpoint per usb frame to save cpu usage. Default to 1 NAK per endpoint --- examples/host/bare_api/src/tusb_config.h | 1 - examples/host/cdc_msc_hid/src/tusb_config.h | 1 - .../cdc_msc_hid_freertos/src/tusb_config.h | 1 - .../host/hid_controller/src/tusb_config.h | 1 - .../host/msc_file_explorer/src/tusb_config.h | 1 - src/portable/analog/max3421/hcd_max3421.c | 142 +++++++----------- 6 files changed, 55 insertions(+), 92 deletions(-) diff --git a/examples/host/bare_api/src/tusb_config.h b/examples/host/bare_api/src/tusb_config.h index d8e81aa82..432446e94 100644 --- a/examples/host/bare_api/src/tusb_config.h +++ b/examples/host/bare_api/src/tusb_config.h @@ -72,7 +72,6 @@ #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 - // #define CFG_TUH_MAX3421_MAX_ATTEMPTS_PER_FRAME 3 // max. transfer attempts per frame // 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) diff --git a/examples/host/cdc_msc_hid/src/tusb_config.h b/examples/host/cdc_msc_hid/src/tusb_config.h index 8a56ebc2b..a59a0ffb9 100644 --- a/examples/host/cdc_msc_hid/src/tusb_config.h +++ b/examples/host/cdc_msc_hid/src/tusb_config.h @@ -72,7 +72,6 @@ #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 - // #define CFG_TUH_MAX3421_MAX_ATTEMPTS_PER_FRAME 3 // max. transfer attempts per frame // 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) 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 7705be5c8..35de5ee50 100644 --- a/examples/host/cdc_msc_hid_freertos/src/tusb_config.h +++ b/examples/host/cdc_msc_hid_freertos/src/tusb_config.h @@ -77,7 +77,6 @@ #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 - // #define CFG_TUH_MAX3421_MAX_ATTEMPTS_PER_FRAME 3 // max. transfer attempts per frame // 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) diff --git a/examples/host/hid_controller/src/tusb_config.h b/examples/host/hid_controller/src/tusb_config.h index f087a93cf..3ac591d8f 100644 --- a/examples/host/hid_controller/src/tusb_config.h +++ b/examples/host/hid_controller/src/tusb_config.h @@ -72,7 +72,6 @@ #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 - // #define CFG_TUH_MAX3421_MAX_ATTEMPTS_PER_FRAME 3 // max. transfer attempts per frame // 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) diff --git a/examples/host/msc_file_explorer/src/tusb_config.h b/examples/host/msc_file_explorer/src/tusb_config.h index 05b9fa174..c798b4383 100644 --- a/examples/host/msc_file_explorer/src/tusb_config.h +++ b/examples/host/msc_file_explorer/src/tusb_config.h @@ -72,7 +72,6 @@ #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 - // #define CFG_TUH_MAX3421_MAX_ATTEMPTS_PER_FRAME 3 // max. transfer attempts per frame // 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) diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index 324638cb8..3eb3f796f 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -167,33 +167,15 @@ enum { }; enum { - EP_STATE_IDLE = 0, - EP_STATE_ATTEMPT1 = 1, // pending 1st attempt - #if CFG_TUH_MAX3421_MAX_ATTEMPTS_PER_FRAME - EP_STATE_ATTEMPT2 = 2, // don't change order - EP_STATE_ATTEMPT3 = 3, // need to be incrementable - EP_STATE_ATTEMPT4 = 4, - EP_STATE_ATTEMPT5 = 5, - EP_STATE_ATTEMPT6 = 6, - EP_STATE_ATTEMPT7 = 7, - EP_STATE_ATTEMPT8 = 8, - EP_STATE_ATTEMPT9 = 9, - EP_STATE_ATTEMPT10 = 10, - EP_STATE_SUSPENDED, // keep next behind last attempt - #endif - EP_STATE_COMPLETE, - EP_STATE_QUANTITY // not used. only to get quantity. keep last + MAX_NAK_DEFAULT = 1 // Number of NAK per endpoint per usb frame }; -TU_VERIFY_STATIC(EP_STATE_QUANTITY <= 16, "no more than 16 states possible. ep->state has 4 bits"); - -#if CFG_TUH_MAX3421_MAX_ATTEMPTS_PER_FRAME - #define EP_STATE_ATTEMPT_QUANTITY (EP_STATE_SUSPENDED - 1) - TU_VERIFY_STATIC(CFG_TUH_MAX3421_MAX_ATTEMPTS_PER_FRAME >= 1 && - CFG_TUH_MAX3421_MAX_ATTEMPTS_PER_FRAME <= EP_STATE_ATTEMPT_QUANTITY, "unsupported attempt quantity"); -#else - #define EP_STATE_ATTEMPT_QUANTITY 1 -#endif +enum { + EP_STATE_IDLE = 0, + EP_STATE_COMPLETE, + EP_STATE_ATTEMPT_1, // pending 1st attempt + EP_STATE_ATTEMPT_MAX = 15 +}; //--------------------------------------------------------------------+ // @@ -223,6 +205,8 @@ typedef struct { TU_VERIFY_STATIC(sizeof(max3421_ep_t) == 12, "size is not correct"); typedef struct { + volatile uint16_t frame_count; + // cached register uint8_t sndbc; uint8_t hirq; @@ -232,17 +216,17 @@ typedef struct { uint8_t hxfr; atomic_flag busy; // busy transferring - volatile uint16_t frame_count; - max3421_ep_t ep[CFG_TUH_MAX3421_ENDPOINT_TOTAL]; // [0] is reserved for addr0 - - OSAL_MUTEX_DEF(spi_mutexdef); #if OSAL_MUTEX_REQUIRED + OSAL_MUTEX_DEF(spi_mutexdef); osal_mutex_t spi_mutex; #endif + + max3421_ep_t ep[CFG_TUH_MAX3421_ENDPOINT_TOTAL]; // [0] is reserved for addr0 } max3421_data_t; static max3421_data_t _hcd_data; +static uint8_t _max_nak = MAX_NAK_DEFAULT; // max NAK before giving up in a usb frame //--------------------------------------------------------------------+ // API: SPI transfer with MAX3421E @@ -332,7 +316,6 @@ static void fifo_write(uint8_t rhport, uint8_t reg, uint8_t const * buffer, uint 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) { @@ -421,18 +404,22 @@ static void free_ep(uint8_t daddr) { } } +// Check if endpoint has an queued transfer +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 && state < EP_STATE_ATTEMPT_1 + _max_nak; +} + +// Find the next pending endpoint using round-robin scheduling, starting from next endpoint. +// return NULL if not found +// TODO respect interrupt endpoint's interval static max3421_ep_t * find_next_pending_ep(max3421_ep_t * cur_ep) { - // search for next pending endpoint using round-robin scheduling - // if no other endpoint is pending and current endpoint is still pending, the current endpoint will be returned - // if no other endpoint is pending and current endpoint is not pending, NULL will be returned - // TODO maybe prioritisation control/interrupt/bulk/iso size_t const idx = (size_t) (cur_ep - _hcd_data.ep); // starting from next endpoint for (size_t i = idx + 1; i < CFG_TUH_MAX3421_ENDPOINT_TOTAL; i++) { max3421_ep_t* ep = &_hcd_data.ep[i]; - if (ep->state >= EP_STATE_ATTEMPT1 && ep->state <= EP_STATE_ATTEMPT_QUANTITY && ep->packet_size) { -// TU_LOG3("next pending i = %u\r\n", i); + if (is_ep_pending(ep)) { return ep; } } @@ -440,8 +427,7 @@ static max3421_ep_t * find_next_pending_ep(max3421_ep_t * cur_ep) { // wrap around including current endpoint for (size_t i = 0; i <= idx; i++) { max3421_ep_t* ep = &_hcd_data.ep[i]; - if (ep->state >= EP_STATE_ATTEMPT1 && ep->state <= EP_STATE_ATTEMPT_QUANTITY && ep->packet_size) { -// TU_LOG3("next pending i = %u\r\n", i); + if (is_ep_pending(ep)) { return ep; } } @@ -469,7 +455,9 @@ bool hcd_init(uint8_t rhport) { tuh_max3421_int_api(rhport, false); TU_LOG2_INT(sizeof(max3421_ep_t)); + TU_LOG2_INT(sizeof(atomic_flag)); TU_LOG2_INT(sizeof(max3421_data_t)); + TU_LOG2_INT(offsetof(max3421_data_t, ep)); tu_memclr(&_hcd_data, sizeof(_hcd_data)); _hcd_data.peraddr = 0xff; // invalid @@ -689,7 +677,7 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t daddr, uint8_t ep_addr, uint8_t * buf ep->buf = buffer; ep->total_len = buflen; ep->xferred_len = 0; - ep->state = EP_STATE_ATTEMPT1; + ep->state = EP_STATE_ATTEMPT_1; if ( ep_num == 0 ) { ep->is_setup = 0; @@ -726,7 +714,7 @@ bool hcd_setup_send(uint8_t rhport, uint8_t daddr, uint8_t const setup_packet[8] ep->buf = (uint8_t*)(uintptr_t) setup_packet; ep->total_len = 8; ep->xferred_len = 0; - ep->state = EP_STATE_ATTEMPT1; + ep->state = EP_STATE_ATTEMPT_1; // carry out transfer if not busy if ( !atomic_flag_test_and_set(&_hcd_data.busy) ) { @@ -839,40 +827,24 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) { break; case HRSL_NAK: - // TODO no retry for iso in current frame - // TODO retry limitation over all (not only per frame) if (ep_num == 0) { - // setup/control => retry immediately + // control endpoint -> retry immediately hxfr_write(rhport, _hcd_data.hxfr, in_isr); - #if CFG_TUH_MAX3421_MAX_ATTEMPTS_PER_FRAME - } else if (ep->state == CFG_TUH_MAX3421_MAX_ATTEMPTS_PER_FRAME) { - // no more retry this frame if max. attempts are reached => suspend and retry it next frame - ep->state = EP_STATE_SUSPENDED; - - max3421_ep_t * next_ep = find_next_pending_ep(ep); - if (next_ep) { - // switch to next pending endpoint TODO could have issue with double buffered if not clear previously out data - xact_inout(rhport, next_ep, true, in_isr); - } else { - // no more pending => clear busy - atomic_flag_clear(&_hcd_data.busy); - } - #endif } else { - // another attempt - #if CFG_TUH_MAX3421_MAX_ATTEMPTS_PER_FRAME + if (ep->state < EP_STATE_ATTEMPT_MAX) { ep->state++; - #endif + } max3421_ep_t * next_ep = find_next_pending_ep(ep); if (ep == next_ep) { - // this endpoint is only one pending => retry immediately + // 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_inout(rhport, next_ep, true, in_isr); } else { - TU_ASSERT(false,); + // no more pending in this frame -> clear busy + atomic_flag_clear(&_hcd_data.busy); } } return; @@ -957,28 +929,24 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { if (hirq & HIRQ_FRAME_IRQ) { _hcd_data.frame_count++; - #if CFG_TUH_MAX3421_MAX_ATTEMPTS_PER_FRAME - // endpoints retry or restart attempt next frame - for (size_t i = 0; i < CFG_TUH_MAX3421_ENDPOINT_TOTAL; i++) { - max3421_ep_t * ep = &_hcd_data.ep[i]; + max3421_ep_t* ep_retry = NULL; - // retry the endpoints that are suspended (NAK) last frame - if (ep->state == EP_STATE_SUSPENDED) { - // resume and retry suspended endpoint with attempt 1 - ep->state = EP_STATE_ATTEMPT1; + // 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) { + ep->state = EP_STATE_ATTEMPT_1; - if (ep->packet_size) { // first test packet_size before atomic_flag_test_and_set() - if (!atomic_flag_test_and_set(&_hcd_data.busy) ) { - // trigger endpoint to be retried - xact_inout(rhport, ep, true, in_isr); - } - } - } else if (ep->state > EP_STATE_ATTEMPT1 && ep->state <= CFG_TUH_MAX3421_MAX_ATTEMPTS_PER_FRAME) { - // restart all other running/pending endpoints - ep->state = EP_STATE_ATTEMPT1; + if (ep_retry == NULL) { + ep_retry = ep; } } - #endif + } + + // start usb transfer if not busy + if (ep_retry != NULL && !atomic_flag_test_and_set(&_hcd_data.busy)) { + xact_inout(rhport, ep_retry, true, in_isr); + } } if (hirq & HIRQ_CONDET_IRQ) { @@ -987,17 +955,17 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { // queue more transfer in handle_xfer_done() can cause hirq to be set again while external IRQ may not catch and/or // 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 ) { + while (hirq & (HIRQ_RCVDAV_IRQ | HIRQ_HXFRDN_IRQ)) { + if (hirq & HIRQ_RCVDAV_IRQ) { uint8_t const ep_num = _hcd_data.hxfr & HXFR_EPNUM_MASK; - max3421_ep_t *ep = find_opened_ep(_hcd_data.peraddr, ep_num, 1); + 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 ) { + while (hirq & HIRQ_RCVDAV_IRQ) { 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 ) { + if (xact_len) { fifo_read(rhport, ep->buf, xact_len, in_isr); ep->buf += xact_len; ep->xferred_len += xact_len; @@ -1008,12 +976,12 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { hirq = reg_read(rhport, HIRQ_ADDR, in_isr); } - if ( xact_len < ep->packet_size || ep->xferred_len >= ep->total_len ) { + if (xact_len < ep->packet_size || ep->xferred_len >= ep->total_len) { ep->state = EP_STATE_COMPLETE; } } - if ( hirq & HIRQ_HXFRDN_IRQ ) { + if (hirq & HIRQ_HXFRDN_IRQ) { hirq_write(rhport, HIRQ_HXFRDN_IRQ, in_isr); handle_xfer_done(rhport, in_isr); } From e802fe0677c901a444e7c9b5d67be2a1f400adee Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 2 Apr 2024 14:28:41 +0700 Subject: [PATCH 210/454] refactor: add hxfr per endpoint --- src/portable/analog/max3421/hcd_max3421.c | 100 +++++++++++----------- src/tusb_option.h | 13 +-- 2 files changed, 52 insertions(+), 61 deletions(-) diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index 3eb3f796f..1b182e551 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -184,17 +184,21 @@ enum { typedef struct { uint8_t daddr; - struct TU_ATTR_PACKED { - uint8_t state : 4; - uint8_t is_setup : 1; // also bit 4 in HXFR reg (smaller code, no shift necessary) - uint8_t ep_dir : 1; // also bit 5 in HXFR reg (smaller code, no shift necessary) - uint8_t is_iso : 1; // also bit 6 in HXFR reg (smaller code, no shift necessary) - uint8_t data_toggle : 1; + 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; + + uint8_t hxfr; }; struct TU_ATTR_PACKED { - uint8_t ep_num : 4; - uint16_t packet_size : 12; + uint8_t state : 4; + uint8_t data_toggle : 1; + uint16_t packet_size : 11; }; uint16_t total_len; @@ -370,10 +374,11 @@ TU_ATTR_ALWAYS_INLINE static inline void sndbc_write(uint8_t rhport, uint8_t dat //--------------------------------------------------------------------+ static max3421_ep_t* find_ep_not_addr0(uint8_t daddr, uint8_t ep_num, uint8_t ep_dir) { + uint8_t const is_out = 1-ep_dir; for(size_t i=1; idaddr && ep_num == ep->ep_num && (ep_dir == ep->ep_dir || ep_num == 0)) { + // control endpoint is bi-direction (skip check) + if (daddr == ep->daddr && ep_num == ep->hxfr_bm.ep_num && (ep_num == 0 || is_out == ep->hxfr_bm.is_out)) { return ep; } } @@ -577,7 +582,6 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { // Open an endpoint bool hcd_edpt_open(uint8_t rhport, uint8_t daddr, tusb_desc_endpoint_t const * ep_desc) { (void) rhport; - (void) daddr; uint8_t const ep_num = tu_edpt_number(ep_desc->bEndpointAddress); tusb_dir_t const ep_dir = tu_edpt_dir(ep_desc->bEndpointAddress); @@ -589,12 +593,9 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t daddr, tusb_desc_endpoint_t const * e ep = allocate_ep(); TU_ASSERT(ep); ep->daddr = daddr; - ep->ep_num = (uint8_t) (ep_num & 0x0f); - ep->ep_dir = (ep_dir == TUSB_DIR_IN) ? 1 : 0; - } - - if ( TUSB_XFER_ISOCHRONOUS == ep_desc->bmAttributes.xfer ) { - ep->is_iso = 1; + ep->hxfr_bm.ep_num = (uint8_t) (ep_num & 0x0f); + ep->hxfr_bm.is_out = (ep_dir == TUSB_DIR_OUT) ? 1 : 0; + ep->hxfr_bm.is_iso = (TUSB_XFER_ISOCHRONOUS == ep_desc->bmAttributes.xfer) ? 1 : 0; } ep->packet_size = (uint16_t) (tu_edpt_packet_size(ep_desc) & 0x7ff); @@ -602,7 +603,7 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t daddr, tusb_desc_endpoint_t const * e return true; } -void xact_out(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_isr) { +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 if (switch_ep) { @@ -618,12 +619,10 @@ void xact_out(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_isr) { fifo_write(rhport, SNDFIFO_ADDR, ep->buf, xact_len, in_isr); } sndbc_write(rhport, xact_len, in_isr); - - uint8_t const hxfr = (uint8_t ) (ep->ep_num | HXFR_OUT_NIN | (ep->is_iso ? HXFR_ISO : 0)); - hxfr_write(rhport, hxfr, in_isr); + hxfr_write(rhport, ep->hxfr, in_isr); } -void xact_in(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_isr) { +static void xact_in(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_isr) { // Page 13: Programming BULK-IN Transfers if (switch_ep) { peraddr_write(rhport, ep->daddr, in_isr); @@ -632,34 +631,36 @@ void xact_in(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_isr) { reg_write(rhport, HCTL_ADDR, hctl, in_isr); } - uint8_t const hxfr = (uint8_t) (ep->ep_num | (ep->is_iso ? HXFR_ISO : 0)); - hxfr_write(rhport, hxfr, in_isr); + hxfr_write(rhport, ep->hxfr, in_isr); } -TU_ATTR_ALWAYS_INLINE static inline -void xact_inout(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_isr) { - if (ep->ep_num == 0 ) { +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); + hxfr_write(rhport, HXFR_SETUP, in_isr); +} + +static void xact_generic(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_isr) { + if (ep->hxfr_bm.ep_num == 0 ) { // setup - if (ep->is_setup) { - peraddr_write(rhport, ep->daddr, in_isr); - fifo_write(rhport, SUDFIFO_ADDR, ep->buf, 8, in_isr); - hxfr_write(rhport, HXFR_SETUP, in_isr); + if (ep->hxfr_bm.is_setup) { + xact_setup(rhport, ep, in_isr); return; } // status if (ep->buf == NULL || ep->total_len == 0) { - uint8_t const hxfr = HXFR_HS | (ep->ep_dir ? 0 : HXFR_OUT_NIN); + uint8_t const hxfr = HXFR_HS | (ep->hxfr_bm.is_out ? HXFR_OUT_NIN : 0); peraddr_write(rhport, ep->daddr, in_isr); hxfr_write(rhport, hxfr, in_isr); return; } } - if (ep->ep_dir) { - xact_in(rhport, ep, switch_ep, in_isr); - }else { + if (ep->hxfr_bm.is_out) { xact_out(rhport, ep, switch_ep, in_isr); + }else { + xact_in(rhport, ep, switch_ep, in_isr); } } @@ -672,21 +673,21 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t daddr, uint8_t ep_addr, uint8_t * buf TU_VERIFY(ep); // control transfer can switch direction - ep->ep_dir = ep_dir ? 1u : 0u; + ep->hxfr_bm.is_out = ep_dir ? 0u : 1u; ep->buf = buffer; ep->total_len = buflen; ep->xferred_len = 0; ep->state = EP_STATE_ATTEMPT_1; - if ( ep_num == 0 ) { - ep->is_setup = 0; + if (ep_num == 0) { + ep->hxfr_bm.is_setup = 0; ep->data_toggle = 1; } // carry out transfer if not busy - if ( !atomic_flag_test_and_set(&_hcd_data.busy) ) { - xact_inout(rhport, ep, true, false); + if (!atomic_flag_test_and_set(&_hcd_data.busy)) { + xact_generic(rhport, ep, true, false); } return true; @@ -709,16 +710,16 @@ bool hcd_setup_send(uint8_t rhport, uint8_t daddr, uint8_t const setup_packet[8] max3421_ep_t* ep = find_opened_ep(daddr, 0, 0); TU_ASSERT(ep); - ep->ep_dir = 0; - ep->is_setup = 1; + ep->hxfr_bm.is_out = 1; + ep->hxfr_bm.is_setup = 1; ep->buf = (uint8_t*)(uintptr_t) setup_packet; ep->total_len = 8; ep->xferred_len = 0; ep->state = EP_STATE_ATTEMPT_1; // carry out transfer if not busy - if ( !atomic_flag_test_and_set(&_hcd_data.busy) ) { - xact_inout(rhport, ep, true, false); + if (!atomic_flag_test_and_set(&_hcd_data.busy)) { + xact_setup(rhport, ep, false); } return true; @@ -783,10 +784,11 @@ static void handle_connect_irq(uint8_t rhport, bool in_isr) { } static void xfer_complete_isr(uint8_t rhport, max3421_ep_t *ep, xfer_result_t result, uint8_t hrsl, bool in_isr) { - uint8_t const ep_addr = tu_edpt_addr(ep->ep_num, ep->ep_dir); + uint8_t const ep_dir = 1-ep->hxfr_bm.is_out; + uint8_t const ep_addr = tu_edpt_addr(ep->hxfr_bm.ep_num, ep_dir); // save data toggle - if (ep->ep_dir) { + if (ep_dir) { ep->data_toggle = (hrsl & HRSL_RCVTOGRD) ? 1u : 0u; }else { ep->data_toggle = (hrsl & HRSL_SNDTOGRD) ? 1u : 0u; @@ -798,7 +800,7 @@ static void xfer_complete_isr(uint8_t rhport, max3421_ep_t *ep, xfer_result_t re // Find next pending endpoint max3421_ep_t * next_ep = find_next_pending_ep(ep); if (next_ep) { - xact_inout(rhport, next_ep, true, in_isr); + xact_generic(rhport, next_ep, true, in_isr); }else { // no more pending atomic_flag_clear(&_hcd_data.busy); @@ -841,7 +843,7 @@ 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_inout(rhport, next_ep, true, in_isr); + xact_generic(rhport, next_ep, true, in_isr); } else { // no more pending in this frame -> clear busy atomic_flag_clear(&_hcd_data.busy); @@ -945,7 +947,7 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { // start usb transfer if not busy if (ep_retry != NULL && !atomic_flag_test_and_set(&_hcd_data.busy)) { - xact_inout(rhport, ep_retry, true, in_isr); + xact_generic(rhport, ep_retry, true, in_isr); } } diff --git a/src/tusb_option.h b/src/tusb_option.h index 18cc8a82c..f90fb7026 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -34,7 +34,7 @@ #define TUSB_VERSION_MAJOR 0 #define TUSB_VERSION_MINOR 16 #define TUSB_VERSION_REVISION 0 -#define TUSB_VERSION_BUILD 1 +#define TUSB_VERSION_BUILD 2 #define TUSB_VERSION_NUMBER (TUSB_VERSION_MAJOR << 24 | TUSB_VERSION_MINOR << 16 | TUSB_VERSION_REVISION << 8 | TUSB_VERSION_BUILD) #define TUSB_VERSION_STRING TU_STRING(TUSB_VERSION_MAJOR) "." TU_STRING(TUSB_VERSION_MINOR) "." TU_STRING(TUSB_VERSION_REVISION) @@ -529,17 +529,6 @@ #define CFG_TUH_MAX3421 0 #endif -// MAX3421 Host max. transfer attempts per frame (except control and iso) -// retry quantity = (CFG_TUH_MAX3421_MAX_ATTEMPS_PER_FRAME - 1) -// 0 = endless retries. is default to keep compatibility -// => this may overload MCU with permanently repeating NAK interrupts -// => possible increased USB traffic, increased latencies, reduced data throughput -// a usual attempt quantity is 3 (reference: the book "USB Complete" by Jan Axelson) -#ifndef CFG_TUH_MAX3421_MAX_ATTEMPTS_PER_FRAME - #define CFG_TUH_MAX3421_MAX_ATTEMPTS_PER_FRAME 0 -#endif - - //--------------------------------------------------------------------+ // TypeC Options (Default) //--------------------------------------------------------------------+ From 7d3d60f96de3f6e15291c9302463c294e2dc98de Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 2 Apr 2024 16:38:40 +0700 Subject: [PATCH 211/454] add hcd_configure() to change max NAK dynamically --- src/host/hcd.h | 2 +- src/host/usbh.c | 13 ++++++++----- src/host/usbh.h | 14 ++++++++++++-- src/portable/analog/max3421/hcd_max3421.c | 17 +++++++++++------ src/tusb_option.h | 1 - 5 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/host/hcd.h b/src/host/hcd.h index d5804c608..5547c7cc5 100644 --- a/src/host/hcd.h +++ b/src/host/hcd.h @@ -125,7 +125,7 @@ bool hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) TU_ATTR_W //--------------------------------------------------------------------+ // optional hcd configuration, called by tuh_configure() -bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) TU_ATTR_WEAK; +bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param); // Initialize controller to host mode bool hcd_init(uint8_t rhport); diff --git a/src/host/usbh.c b/src/host/usbh.c index 05091736e..aa0603d47 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -52,6 +52,13 @@ TU_ATTR_WEAK bool hcd_deinit(uint8_t rhport) { return false; } +TU_ATTR_WEAK bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) { + (void) rhport; + (void) cfg_id; + (void) cfg_param; + return false; +} + TU_ATTR_WEAK void tuh_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr) { (void) rhport; (void) eventid; @@ -332,11 +339,7 @@ bool tuh_rhport_reset_bus(uint8_t rhport, bool active) { //--------------------------------------------------------------------+ bool tuh_configure(uint8_t rhport, uint32_t cfg_id, const void *cfg_param) { - if ( hcd_configure ) { - return hcd_configure(rhport, cfg_id, cfg_param); - } else { - return false; - } + return hcd_configure(rhport, cfg_id, cfg_param); } static void clear_device(usbh_device_t* dev) { diff --git a/src/host/usbh.h b/src/host/usbh.h index 0e31e80a7..57362c778 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -73,11 +73,21 @@ typedef struct { tusb_desc_interface_t desc; } tuh_itf_info_t; -// ConfigID for tuh_config() +// ConfigID for tuh_configure() enum { - TUH_CFGID_RPI_PIO_USB_CONFIGURATION = OPT_MCU_RP2040 << 8 // cfg_param: pio_usb_configuration_t + TUH_CFGID_INVALID = 0, + TUH_CFGID_RPI_PIO_USB_CONFIGURATION = 100, // cfg_param: pio_usb_configuration_t + TUH_CFGID_MAX3421 = 200, }; +typedef union { + // For TUH_CFGID_RPI_PIO_USB_CONFIGURATION use pio_usb_configuration_t + + struct { + uint8_t max_nak; + } max3421; +} tuh_configure_param_t; + //--------------------------------------------------------------------+ // APPLICATION CALLBACK //--------------------------------------------------------------------+ diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index 1b182e551..12d80e0b5 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -30,6 +30,7 @@ #include #include "host/hcd.h" +#include "host/usbh.h" //--------------------------------------------------------------------+ // @@ -230,7 +231,9 @@ typedef struct { } max3421_data_t; static max3421_data_t _hcd_data; -static uint8_t _max_nak = MAX_NAK_DEFAULT; // max NAK before giving up in a usb frame + +// max NAK before giving up in a frame. 0 means infinite NAKs +static uint8_t _max_nak = MAX_NAK_DEFAULT; //--------------------------------------------------------------------+ // API: SPI transfer with MAX3421E @@ -409,10 +412,11 @@ static void free_ep(uint8_t daddr) { } } -// Check if endpoint has an queued transfer +// Check if endpoint has an queued transfer and not reach max NAK 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 && state < EP_STATE_ATTEMPT_1 + _max_nak; + return ep->packet_size && (state >= EP_STATE_ATTEMPT_1) && + (_max_nak == 0 || state < EP_STATE_ATTEMPT_1 + _max_nak); } // Find the next pending endpoint using round-robin scheduling, starting from next endpoint. @@ -447,10 +451,11 @@ static max3421_ep_t * find_next_pending_ep(max3421_ep_t * cur_ep) { // optional hcd configuration, called by tuh_configure() bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) { (void) rhport; - (void) cfg_id; - (void) cfg_param; + TU_VERIFY(cfg_id == TUH_CFGID_MAX3421); - return false; + tuh_configure_param_t const* cfg = (tuh_configure_param_t const*) cfg_param; + _max_nak = cfg->max3421.max_nak; + return true; } // Initialize controller to host mode diff --git a/src/tusb_option.h b/src/tusb_option.h index f90fb7026..812074c44 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -144,7 +144,6 @@ #define OPT_MCU_RX72N 1402 ///< Renesas RX72N #define OPT_MCU_RAXXX 1403 ///< Renesas RAxxx families - // Mind Motion #define OPT_MCU_MM32F327X 1500 ///< Mind Motion MM32F327 From 172c9f70c74c541892006ff2bbfea818f40a235a Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 2 Apr 2024 16:55:49 +0700 Subject: [PATCH 212/454] clean up --- src/portable/analog/max3421/hcd_max3421.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index 12d80e0b5..61a7e2703 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -173,8 +173,8 @@ enum { enum { EP_STATE_IDLE = 0, - EP_STATE_COMPLETE, - EP_STATE_ATTEMPT_1, // pending 1st attempt + EP_STATE_COMPLETE = 1, + EP_STATE_ATTEMPT_1 = 2, // pending 1st attempt EP_STATE_ATTEMPT_MAX = 15 }; @@ -465,7 +465,6 @@ bool hcd_init(uint8_t rhport) { tuh_max3421_int_api(rhport, false); TU_LOG2_INT(sizeof(max3421_ep_t)); - TU_LOG2_INT(sizeof(atomic_flag)); TU_LOG2_INT(sizeof(max3421_data_t)); TU_LOG2_INT(offsetof(max3421_data_t, ep)); @@ -873,7 +872,9 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) { if (ep_dir) { // IN transfer: fifo data is already received in RCVDAV IRQ - if ( hxfr_type & HXFR_HS ) { + + // mark control handshake as complete + if (hxfr_type & HXFR_HS) { ep->state = EP_STATE_COMPLETE; } From f2859287df706e8016d661eea90a8c0b79d9d8a4 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 2 Apr 2024 17:11:22 +0700 Subject: [PATCH 213/454] check for PWR_USBSCR_USB33DEN before enabling USB VDD --- hw/bsp/stm32h5/boards/stm32h503nucleo/board.h | 4 ---- hw/bsp/stm32h5/boards/stm32h563nucleo/board.h | 4 ---- hw/bsp/stm32h5/boards/stm32h573i_dk/board.h | 5 ----- hw/bsp/stm32h5/family.c | 4 +++- 4 files changed, 3 insertions(+), 14 deletions(-) diff --git a/hw/bsp/stm32h5/boards/stm32h503nucleo/board.h b/hw/bsp/stm32h5/boards/stm32h503nucleo/board.h index 531f00425..da20cfa3a 100644 --- a/hw/bsp/stm32h5/boards/stm32h503nucleo/board.h +++ b/hw/bsp/stm32h5/boards/stm32h503nucleo/board.h @@ -115,10 +115,6 @@ static inline void SystemClock_Config(void) { __HAL_RCC_USB_CLK_ENABLE(); } -static inline void board_enable_vdd_usb(void) { - // USB in STM32H503RB does not require enabling VDD -} - #ifdef __cplusplus } #endif diff --git a/hw/bsp/stm32h5/boards/stm32h563nucleo/board.h b/hw/bsp/stm32h5/boards/stm32h563nucleo/board.h index 13eaed6aa..8e849f5c8 100644 --- a/hw/bsp/stm32h5/boards/stm32h563nucleo/board.h +++ b/hw/bsp/stm32h5/boards/stm32h563nucleo/board.h @@ -122,10 +122,6 @@ static inline void SystemClock_Config(void) { __HAL_RCC_USB_CLK_ENABLE(); } -static inline void board_enable_vdd_usb(void) { - /* Enable VDDUSB to power on USB peripheral */ - HAL_PWREx_EnableVddUSB(); -} #ifdef __cplusplus } #endif diff --git a/hw/bsp/stm32h5/boards/stm32h573i_dk/board.h b/hw/bsp/stm32h5/boards/stm32h573i_dk/board.h index b98939cc1..674cf8e2a 100644 --- a/hw/bsp/stm32h5/boards/stm32h573i_dk/board.h +++ b/hw/bsp/stm32h5/boards/stm32h573i_dk/board.h @@ -108,11 +108,6 @@ static inline void SystemClock_Config(void) { __HAL_RCC_USB_CLK_ENABLE(); } -static inline void board_enable_vdd_usb(void) { - /* Enable VDDUSB to power on USB peripheral */ - HAL_PWREx_EnableVddUSB(); -} - #ifdef __cplusplus } #endif diff --git a/hw/bsp/stm32h5/family.c b/hw/bsp/stm32h5/family.c index 4eb846933..81c0ef4ce 100644 --- a/hw/bsp/stm32h5/family.c +++ b/hw/bsp/stm32h5/family.c @@ -145,7 +145,9 @@ void board_init(void) { __HAL_RCC_USB_CLK_ENABLE(); /* Enable VDDUSB */ - board_enable_vdd_usb(); + #if defined (PWR_USBSCR_USB33DEN) + HAL_PWREx_EnableVddUSB(); + #endif } //--------------------------------------------------------------------+ From d692d5ab3ad4926474e0932e27551405e82eebe9 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Tue, 2 Apr 2024 14:17:24 +0200 Subject: [PATCH 214/454] Move endpoint alloc define to tusb_mcu.h --- src/class/audio/audio_device.c | 19 ++++++------------- src/common/tusb_mcu.h | 4 ++++ 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 293defd96..5ca02f39b 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -96,13 +96,6 @@ #define USE_LINEAR_BUFFER 1 #endif -// Temporarily put the check here -#if defined(TUP_USBIP_FSDEV) || defined(TUP_USBIP_DWC2) - #define USE_ISO_EP_ALLOCATION 1 -#else - #define USE_ISO_EP_ALLOCATION 0 -#endif - // Declaration of buffers // Check for maximum supported numbers @@ -1483,7 +1476,7 @@ uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin #endif } -#if USE_ISO_EP_ALLOCATION +#ifdef TUP_DCD_EDPT_ISO_ALLOC { #if CFG_TUD_AUDIO_ENABLE_EP_IN uint8_t ep_in = 0; @@ -1559,7 +1552,7 @@ uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin } #endif } -#endif // USE_ISO_EP_ALLOCATION +#endif // TUP_DCD_EDPT_ISO_ALLOC #if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL { @@ -1655,7 +1648,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * if (audio->ep_in_as_intf_num == itf) { audio->ep_in_as_intf_num = 0; - #if !USE_ISO_EP_ALLOCATION + #ifndef TUP_DCD_EDPT_ISO_ALLOC usbd_edpt_close(rhport, audio->ep_in); #endif @@ -1686,7 +1679,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * if (audio->ep_out_as_intf_num == itf) { audio->ep_out_as_intf_num = 0; - #if !USE_ISO_EP_ALLOCATION + #ifndef TUP_DCD_EDPT_ISO_ALLOC usbd_edpt_close(rhport, audio->ep_out); #endif @@ -1707,7 +1700,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * // Close corresponding feedback EP #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP - #if !USE_ISO_EP_ALLOCATION + #ifndef TUP_DCD_EDPT_ISO_ALLOC usbd_edpt_close(rhport, audio->ep_fb); #endif audio->ep_fb = 0; @@ -1739,7 +1732,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) { tusb_desc_endpoint_t const* desc_ep = (tusb_desc_endpoint_t const *) p_desc; -#if USE_ISO_EP_ALLOCATION +#ifdef TUP_DCD_EDPT_ISO_ALLOC TU_ASSERT(usbd_edpt_iso_activate(rhport, desc_ep)); #else TU_ASSERT(usbd_edpt_open(rhport, desc_ep)); diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 308ee713c..1ee20ba07 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -434,4 +434,8 @@ #define TU_ATTR_FAST_FUNC #endif +#if defined(TUP_USBIP_DWC2) || defined(TUP_USBIP_FSDEV) + #define TUP_DCD_EDPT_ISO_ALLOC +#endif + #endif From 8936096846f3b4e0f6d2193b5f8be74a94d003f9 Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Tue, 2 Apr 2024 19:56:39 +0700 Subject: [PATCH 215/454] max3421 limit max nak --- src/portable/analog/max3421/hcd_max3421.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index 61a7e2703..9e363506c 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -454,7 +454,7 @@ bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) { TU_VERIFY(cfg_id == TUH_CFGID_MAX3421); tuh_configure_param_t const* cfg = (tuh_configure_param_t const*) cfg_param; - _max_nak = cfg->max3421.max_nak; + _max_nak = tu_max8(cfg->max3421.max_nak, EP_STATE_ATTEMPT_MAX-EP_STATE_ATTEMPT_1); return true; } From 7cd947f96c17c88896f4a46bf96ff6ca977fdb86 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Tue, 2 Apr 2024 15:29:16 +0200 Subject: [PATCH 216/454] Add endpoint ISO allocation to video class. --- src/class/video/video_device.c | 47 ++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index 5306356ba..648c8c3c8 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -759,10 +759,15 @@ static bool _open_vs_itf(uint8_t rhport, videod_streaming_interface_t *stm, uint for (i = 0; i < TU_ARRAY_SIZE(stm->desc.ep); ++i) { uint_fast16_t ofs_ep = stm->desc.ep[i]; if (!ofs_ep) break; - uint8_t ep_adr = _desc_ep_addr(desc + ofs_ep); - usbd_edpt_close(rhport, ep_adr); - stm->desc.ep[i] = 0; - TU_LOG_DRV(" close EP%02x\r\n", ep_adr); + tusb_desc_endpoint_t const *ep = (tusb_desc_endpoint_t const*)(desc + ofs_ep); + /* Only ISO endpoints needs to be closed */ + if(ep->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) { +#ifndef TUP_DCD_EDPT_ISO_ALLOC + usbd_edpt_close(rhport, ep->bEndpointAddress); +#endif + stm->desc.ep[i] = 0; + TU_LOG_DRV(" close EP%02x\r\n", ep->bEndpointAddress); + } } /* clear transfer management information */ @@ -788,16 +793,18 @@ static bool _open_vs_itf(uint8_t rhport, videod_streaming_interface_t *stm, uint TU_ASSERT(cur < end); tusb_desc_endpoint_t const *ep = (tusb_desc_endpoint_t const*)cur; uint_fast32_t max_size = stm->max_payload_transfer_size; - if (altnum) { - if ((TUSB_XFER_ISOCHRONOUS == ep->bmAttributes.xfer) && - (tu_edpt_packet_size(ep) < max_size)) { - /* FS must be less than or equal to max packet size */ - return false; - } + if (altnum && (TUSB_XFER_ISOCHRONOUS == ep->bmAttributes.xfer)) { + /* FS must be less than or equal to max packet size */ + TU_VERIFY (tu_edpt_packet_size(ep) >= max_size); +#ifdef TUP_DCD_EDPT_ISO_ALLOC + usbd_edpt_iso_activate(rhport, ep); +#else + TU_ASSERT(usbd_edpt_open(rhport, ep)); +#endif } else { TU_VERIFY(TUSB_XFER_BULK == ep->bmAttributes.xfer); + TU_ASSERT(usbd_edpt_open(rhport, ep)); } - TU_ASSERT(usbd_edpt_open(rhport, ep)); stm->desc.ep[i] = (uint16_t) (cur - desc); TU_LOG_DRV(" open EP%02x\r\n", _desc_ep_addr(cur)); } @@ -1283,6 +1290,24 @@ uint16_t videod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin cur = _next_desc_itf(cur, end); stm->desc.end = (uint16_t) ((uintptr_t)cur - (uintptr_t)itf_desc); stm->state = VS_STATE_PROBING; +#ifdef TUP_DCD_EDPT_ISO_ALLOC + /* Allocate ISO endpoints */ + uint16_t ep_size = 0; + uint16_t ep_addr = 0; + uint8_t const *p_desc = (uint8_t const*)itf_desc + stm->desc.beg; + uint8_t const *p_desc_end = (uint8_t const*)itf_desc + stm->desc.end; + while (p_desc < p_desc_end) { + if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) { + tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) p_desc; + if (desc_ep->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) { + ep_addr = desc_ep->bEndpointAddress; + ep_size = TU_MAX(tu_edpt_packet_size(desc_ep), ep_size); + } + } + p_desc = tu_desc_next(p_desc); + } + if(ep_addr > 0 && ep_size > 0) usbd_edpt_iso_alloc(rhport, ep_addr, ep_size); +#endif if (0 == stm_idx && 1 == bInCollection) { /* If there is only one streaming interface and no alternate settings, * host may not issue set_interface so open the streaming interface here. */ From 9fb1fb90447fbbfdc3ca33c39cbd75bb807a7907 Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Tue, 2 Apr 2024 20:39:06 +0700 Subject: [PATCH 217/454] correct max nak --- src/portable/analog/max3421/hcd_max3421.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index 9e363506c..fa6d45d3e 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -454,7 +454,7 @@ bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) { TU_VERIFY(cfg_id == TUH_CFGID_MAX3421); tuh_configure_param_t const* cfg = (tuh_configure_param_t const*) cfg_param; - _max_nak = tu_max8(cfg->max3421.max_nak, EP_STATE_ATTEMPT_MAX-EP_STATE_ATTEMPT_1); + _max_nak = tu_min8(cfg->max3421.max_nak, EP_STATE_ATTEMPT_MAX-EP_STATE_ATTEMPT_1); return true; } From f8dc3b97beae611c0a68ab50b960dd1922a66f5d Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Tue, 2 Apr 2024 22:47:50 +0700 Subject: [PATCH 218/454] check cfg_param pointer --- src/portable/analog/max3421/hcd_max3421.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index fa6d45d3e..242c65501 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -451,7 +451,7 @@ static max3421_ep_t * find_next_pending_ep(max3421_ep_t * cur_ep) { // optional hcd configuration, called by tuh_configure() bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) { (void) rhport; - TU_VERIFY(cfg_id == TUH_CFGID_MAX3421); + TU_VERIFY(cfg_id == TUH_CFGID_MAX3421 && cfg_param != NULL); tuh_configure_param_t const* cfg = (tuh_configure_param_t const*) cfg_param; _max_nak = tu_min8(cfg->max3421.max_nak, EP_STATE_ATTEMPT_MAX-EP_STATE_ATTEMPT_1); From db28437218244ae9a1e16d87964edd51f78f54bd Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Tue, 2 Apr 2024 14:17:24 +0200 Subject: [PATCH 219/454] Move endpoint alloc define to tusb_mcu.h --- src/class/audio/audio_device.c | 19 ++++++------------- src/common/tusb_mcu.h | 4 ++++ 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 9a361419b..2af3da324 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -96,13 +96,6 @@ #define USE_LINEAR_BUFFER 1 #endif -// Temporarily put the check here -#if defined(TUP_USBIP_FSDEV) || defined(TUP_USBIP_DWC2) - #define USE_ISO_EP_ALLOCATION 1 -#else - #define USE_ISO_EP_ALLOCATION 0 -#endif - // Declaration of buffers // Check for maximum supported numbers @@ -1476,7 +1469,7 @@ uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin #endif } -#if USE_ISO_EP_ALLOCATION +#ifdef TUP_DCD_EDPT_ISO_ALLOC { #if CFG_TUD_AUDIO_ENABLE_EP_IN uint8_t ep_in = 0; @@ -1552,7 +1545,7 @@ uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin } #endif } -#endif // USE_ISO_EP_ALLOCATION +#endif // TUP_DCD_EDPT_ISO_ALLOC #if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL { @@ -1674,7 +1667,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * if (audio->ep_in_as_intf_num == itf) { audio->ep_in_as_intf_num = 0; - #if !USE_ISO_EP_ALLOCATION + #ifndef TUP_DCD_EDPT_ISO_ALLOC usbd_edpt_close(rhport, audio->ep_in); #endif @@ -1705,7 +1698,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * if (audio->ep_out_as_intf_num == itf) { audio->ep_out_as_intf_num = 0; - #if !USE_ISO_EP_ALLOCATION + #ifndef TUP_DCD_EDPT_ISO_ALLOC usbd_edpt_close(rhport, audio->ep_out); #endif @@ -1726,7 +1719,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * // Close corresponding feedback EP #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP - #if !USE_ISO_EP_ALLOCATION + #ifndef TUP_DCD_EDPT_ISO_ALLOC usbd_edpt_close(rhport, audio->ep_fb); #endif audio->ep_fb = 0; @@ -1758,7 +1751,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) { tusb_desc_endpoint_t const* desc_ep = (tusb_desc_endpoint_t const *) p_desc; -#if USE_ISO_EP_ALLOCATION +#ifdef TUP_DCD_EDPT_ISO_ALLOC TU_ASSERT(usbd_edpt_iso_activate(rhport, desc_ep)); #else TU_ASSERT(usbd_edpt_open(rhport, desc_ep)); diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 308ee713c..1ee20ba07 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -434,4 +434,8 @@ #define TU_ATTR_FAST_FUNC #endif +#if defined(TUP_USBIP_DWC2) || defined(TUP_USBIP_FSDEV) + #define TUP_DCD_EDPT_ISO_ALLOC +#endif + #endif From 2e4d4e4a017202e4aef2a8f3027a29da0f47cd32 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Tue, 2 Apr 2024 15:29:16 +0200 Subject: [PATCH 220/454] Add endpoint ISO allocation to video class. --- src/class/video/video_device.c | 47 ++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index 5306356ba..648c8c3c8 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -759,10 +759,15 @@ static bool _open_vs_itf(uint8_t rhport, videod_streaming_interface_t *stm, uint for (i = 0; i < TU_ARRAY_SIZE(stm->desc.ep); ++i) { uint_fast16_t ofs_ep = stm->desc.ep[i]; if (!ofs_ep) break; - uint8_t ep_adr = _desc_ep_addr(desc + ofs_ep); - usbd_edpt_close(rhport, ep_adr); - stm->desc.ep[i] = 0; - TU_LOG_DRV(" close EP%02x\r\n", ep_adr); + tusb_desc_endpoint_t const *ep = (tusb_desc_endpoint_t const*)(desc + ofs_ep); + /* Only ISO endpoints needs to be closed */ + if(ep->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) { +#ifndef TUP_DCD_EDPT_ISO_ALLOC + usbd_edpt_close(rhport, ep->bEndpointAddress); +#endif + stm->desc.ep[i] = 0; + TU_LOG_DRV(" close EP%02x\r\n", ep->bEndpointAddress); + } } /* clear transfer management information */ @@ -788,16 +793,18 @@ static bool _open_vs_itf(uint8_t rhport, videod_streaming_interface_t *stm, uint TU_ASSERT(cur < end); tusb_desc_endpoint_t const *ep = (tusb_desc_endpoint_t const*)cur; uint_fast32_t max_size = stm->max_payload_transfer_size; - if (altnum) { - if ((TUSB_XFER_ISOCHRONOUS == ep->bmAttributes.xfer) && - (tu_edpt_packet_size(ep) < max_size)) { - /* FS must be less than or equal to max packet size */ - return false; - } + if (altnum && (TUSB_XFER_ISOCHRONOUS == ep->bmAttributes.xfer)) { + /* FS must be less than or equal to max packet size */ + TU_VERIFY (tu_edpt_packet_size(ep) >= max_size); +#ifdef TUP_DCD_EDPT_ISO_ALLOC + usbd_edpt_iso_activate(rhport, ep); +#else + TU_ASSERT(usbd_edpt_open(rhport, ep)); +#endif } else { TU_VERIFY(TUSB_XFER_BULK == ep->bmAttributes.xfer); + TU_ASSERT(usbd_edpt_open(rhport, ep)); } - TU_ASSERT(usbd_edpt_open(rhport, ep)); stm->desc.ep[i] = (uint16_t) (cur - desc); TU_LOG_DRV(" open EP%02x\r\n", _desc_ep_addr(cur)); } @@ -1283,6 +1290,24 @@ uint16_t videod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin cur = _next_desc_itf(cur, end); stm->desc.end = (uint16_t) ((uintptr_t)cur - (uintptr_t)itf_desc); stm->state = VS_STATE_PROBING; +#ifdef TUP_DCD_EDPT_ISO_ALLOC + /* Allocate ISO endpoints */ + uint16_t ep_size = 0; + uint16_t ep_addr = 0; + uint8_t const *p_desc = (uint8_t const*)itf_desc + stm->desc.beg; + uint8_t const *p_desc_end = (uint8_t const*)itf_desc + stm->desc.end; + while (p_desc < p_desc_end) { + if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) { + tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) p_desc; + if (desc_ep->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) { + ep_addr = desc_ep->bEndpointAddress; + ep_size = TU_MAX(tu_edpt_packet_size(desc_ep), ep_size); + } + } + p_desc = tu_desc_next(p_desc); + } + if(ep_addr > 0 && ep_size > 0) usbd_edpt_iso_alloc(rhport, ep_addr, ep_size); +#endif if (0 == stm_idx && 1 == bInCollection) { /* If there is only one streaming interface and no alternate settings, * host may not issue set_interface so open the streaming interface here. */ From 252e630433ff62f9b3ee010f576b5e42e6d7d1e2 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 3 Apr 2024 13:05:53 +0700 Subject: [PATCH 221/454] try catch labeler rest api --- .github/workflows/labeler.yml | 38 ++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index 4733c6f06..947b08ca2 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -28,29 +28,31 @@ jobs: issueOrPrNumber = context.payload.pull_request.number; } - // Check for Adafruit membership - const adafruitResponse = await github.rest.orgs.checkMembershipForUser({ - org: 'adafruit', - username: username - }); - - if (adafruitResponse.status === 204) { - console.log('Adafruit Member'); - label = 'Prio Urgent'; - } else { - // Check if the user is a contributor - const collaboratorResponse = await github.rest.repos.checkCollaborator({ - owner: context.repo.owner, - repo: context.repo.repo, + try { + // Check for Adafruit membership + const adafruitResponse = await github.rest.orgs.checkMembershipForUser({ + org: 'adafruit', username: username }); - if (collaboratorResponse.status === 204) { - console.log('Contributor'); - label = 'Prio Higher'; + if (adafruitResponse.status === 204) { + console.log('Adafruit Member'); + label = 'Prio Urgent'; } else { - console.log('Not a contributor or Adafruit member'); + // If not a Adafruit member, check if the user is a contributor + const collaboratorResponse = await github.rest.repos.checkCollaborator({ + owner: context.repo.owner, + repo: context.repo.repo, + username: username + }); + + if (collaboratorResponse.status === 204) { + console.log('Contributor'); + label = 'Prio Higher'; + } } + } catch (error) { + console.log(`Error processing user ${username}: ${error.message}`); } if (label !== '') { From 594833374c812ccb8b7bac404b7bc7c0fbd56ccf Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 3 Apr 2024 22:24:04 +0700 Subject: [PATCH 222/454] add new example to cmake include list --- examples/device/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/device/CMakeLists.txt b/examples/device/CMakeLists.txt index 0a2e49ef0..c3671da69 100644 --- a/examples/device/CMakeLists.txt +++ b/examples/device/CMakeLists.txt @@ -28,4 +28,5 @@ family_add_subdirectory(net_lwip_webserver) family_add_subdirectory(uac2_headset) family_add_subdirectory(usbtmc) family_add_subdirectory(video_capture) +family_add_subdirectory(video_capture_2ch) family_add_subdirectory(webusb_serial) From 11722cc53393dff71a97b45e63309cb98c463b4b Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 3 Apr 2024 23:08:15 +0700 Subject: [PATCH 223/454] add note for sdk v2 and v3, also add check if allocreq failed --- src/portable/sony/cxd56/dcd_cxd56.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/portable/sony/cxd56/dcd_cxd56.c b/src/portable/sony/cxd56/dcd_cxd56.c index 83cd0718c..41814370e 100644 --- a/src/portable/sony/cxd56/dcd_cxd56.c +++ b/src/portable/sony/cxd56/dcd_cxd56.c @@ -103,19 +103,23 @@ static int _dcd_bind(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_ usbdcd_driver.ep[0] = dev->ep0; #ifdef EP_ALLOCREQ + // SDK v2 usbdcd_driver.req[0] = EP_ALLOCREQ(usbdcd_driver.ep[0]); - if (usbdcd_driver.req[0] != NULL) - { + if (usbdcd_driver.req[0] != NULL) { usbdcd_driver.req[0]->len = 64; usbdcd_driver.req[0]->buf = EP_ALLOCBUFFER(usbdcd_driver.ep[0], 64); - if (!usbdcd_driver.req[0]->buf) - { + if (!usbdcd_driver.req[0]->buf) { EP_FREEREQ(usbdcd_driver.ep[0], usbdcd_driver.req[0]); usbdcd_driver.req[0] = NULL; + return ENOMEM; } } #else - usbdcd_driver.req[0] = usbdev_allocreq(usbdcd_driver.ep[0],64); + // SDK v3 + usbdcd_driver.req[0] = usbdev_allocreq(usbdcd_driver.ep[0], 64); + if (usbdcd_driver.req[0] == NULL) { + return ENOMEM; + } #endif usbdcd_driver.req[0]->callback = usbdcd_ep0incomplete; @@ -301,17 +305,17 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *p_endpoint_desc) usbdcd_driver.req[epnum] = NULL; #ifdef EP_ALLOCREQ + // sdk v2 usbdcd_driver.req[epnum] = EP_ALLOCREQ(usbdcd_driver.ep[epnum]); - if (usbdcd_driver.req[epnum] != NULL) - { + if (usbdcd_driver.req[epnum] != NULL) { usbdcd_driver.req[epnum]->len = ep_mps; } - else #else + // sdk v3 usbdcd_driver.req[epnum] = usbdev_allocreq(usbdcd_driver.ep[epnum], ep_mps); - if(usbdcd_driver.req[epnum] == NULL) #endif - { + + if(usbdcd_driver.req[epnum] == NULL) { return false; } From 7910cc298187327e05c43770b58eac528a4fecfa Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 4 Apr 2024 10:55:14 +0700 Subject: [PATCH 224/454] fix build with rp2040 + max3421 - forward MAX3421_HOST=1 from makefile to cmake - add feather_rp2040_max3421 board to run with ci for rp2040 + max3421 --- examples/build_system/make/make.mk | 1 + .../boards/feather_rp2040_max3421/board.cmake | 4 ++++ src/portable/analog/max3421/hcd_max3421.c | 13 ++++++------- 3 files changed, 11 insertions(+), 7 deletions(-) create mode 100644 hw/bsp/rp2040/boards/feather_rp2040_max3421/board.cmake diff --git a/examples/build_system/make/make.mk b/examples/build_system/make/make.mk index e1113aa52..772befca4 100644 --- a/examples/build_system/make/make.mk +++ b/examples/build_system/make/make.mk @@ -113,6 +113,7 @@ CFLAGS += -DBOARD_$(BOARD_UPPER) ifeq (${MAX3421_HOST},1) SRC_C += src/portable/analog/max3421/hcd_max3421.c CFLAGS += -DCFG_TUH_MAX3421=1 + CMAKE_DEFSYM += -DMAX3421_HOST=1 endif # Log level is mapped to TUSB DEBUG option diff --git a/hw/bsp/rp2040/boards/feather_rp2040_max3421/board.cmake b/hw/bsp/rp2040/boards/feather_rp2040_max3421/board.cmake new file mode 100644 index 000000000..b8e5890f3 --- /dev/null +++ b/hw/bsp/rp2040/boards/feather_rp2040_max3421/board.cmake @@ -0,0 +1,4 @@ +set(PICO_BOARD adafruit_feather_rp2040) + +# Enable MAX3421E USB Host +set(MAX3421_HOST 1) diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index 242c65501..76c1a150b 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -676,19 +676,18 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t daddr, uint8_t ep_addr, uint8_t * buf max3421_ep_t* ep = find_opened_ep(daddr, ep_num, ep_dir); TU_VERIFY(ep); - // control transfer can switch direction - ep->hxfr_bm.is_out = ep_dir ? 0u : 1u; + if (ep_num == 0) { + // control transfer can switch direction + ep->hxfr_bm.is_out = ep_dir ? 0 : 1; + ep->hxfr_bm.is_setup = 0; + ep->data_toggle = 1; + } ep->buf = buffer; ep->total_len = buflen; ep->xferred_len = 0; ep->state = EP_STATE_ATTEMPT_1; - if (ep_num == 0) { - ep->hxfr_bm.is_setup = 0; - ep->data_toggle = 1; - } - // carry out transfer if not busy if (!atomic_flag_test_and_set(&_hcd_data.busy)) { xact_generic(rhport, ep, true, false); From 93fb3b00debc613f631cb6ec848bfcb9231a325c Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 4 Apr 2024 12:51:07 +0700 Subject: [PATCH 225/454] fix build with gcc 11 --- src/portable/analog/max3421/hcd_max3421.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index 76c1a150b..059f674cd 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -654,7 +654,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 = HXFR_HS | (ep->hxfr_bm.is_out ? HXFR_OUT_NIN : 0); + uint8_t const hxfr = (uint8_t) (HXFR_HS | (ep->hxfr & HXFR_OUT_NIN)); peraddr_write(rhport, ep->daddr, in_isr); hxfr_write(rhport, hxfr, in_isr); return; From f603c4a330f55158da7782671158fedabb62c29c Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 4 Apr 2024 13:01:16 +0700 Subject: [PATCH 226/454] skip cdc_msc_hid_freertos example for rp2040 --- examples/host/cdc_msc_hid_freertos/skip.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 examples/host/cdc_msc_hid_freertos/skip.txt diff --git a/examples/host/cdc_msc_hid_freertos/skip.txt b/examples/host/cdc_msc_hid_freertos/skip.txt new file mode 100644 index 000000000..2ba4438fd --- /dev/null +++ b/examples/host/cdc_msc_hid_freertos/skip.txt @@ -0,0 +1 @@ +mcu:RP2040 From ebe692350047b7b2a5b46de7894352934c4200aa Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 4 Apr 2024 14:10:48 +0700 Subject: [PATCH 227/454] update build script to allow skip.txt and only.txt both exist --- hw/bsp/family_support.cmake | 45 ++++++++++++++----------------------- tools/build_utils.py | 21 ++++++++--------- 2 files changed, 28 insertions(+), 38 deletions(-) diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index d84077ed8..4ccd6e4f2 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -79,17 +79,27 @@ set(WARNING_FLAGS_IAR "") function(family_filter RESULT DIR) get_filename_component(DIR ${DIR} ABSOLUTE BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) - if (EXISTS "${DIR}/only.txt") - file(READ "${DIR}/only.txt" ONLYS) - # Replace newlines with semicolon so that it is treated as a list by CMake - string(REPLACE "\n" ";" ONLYS_LINES ${ONLYS}) + if (EXISTS "${DIR}/skip.txt") + file(STRINGS "${DIR}/skip.txt" SKIPS_LINES) + foreach(MCU IN LISTS FAMILY_MCUS) + # For each line in only.txt + foreach(_line ${SKIPS_LINES}) + # If mcu:xxx exists for this mcu then skip + if (${_line} STREQUAL "mcu:${MCU}" OR ${_line} STREQUAL "board:${BOARD}" OR ${_line} STREQUAL "family:${FAMILY}") + set(${RESULT} 0 PARENT_SCOPE) + return() + endif() + endforeach() + endforeach() + endif () - # For each mcu + if (EXISTS "${DIR}/only.txt") + file(STRINGS "${DIR}/only.txt" ONLYS_LINES) foreach(MCU IN LISTS FAMILY_MCUS) # For each line in only.txt foreach(_line ${ONLYS_LINES}) # If mcu:xxx exists for this mcu or board:xxx then include - if (${_line} STREQUAL "mcu:${MCU}" OR ${_line} STREQUAL "board:${BOARD}") + if (${_line} STREQUAL "mcu:${MCU}" OR ${_line} STREQUAL "board:${BOARD}" OR ${_line} STREQUAL "family:${FAMILY}") set(${RESULT} 1 PARENT_SCOPE) return() endif() @@ -98,29 +108,8 @@ function(family_filter RESULT DIR) # Didn't find it in only file so don't build set(${RESULT} 0 PARENT_SCOPE) - - elseif (EXISTS "${DIR}/skip.txt") - file(READ "${DIR}/skip.txt" SKIPS) - # Replace newlines with semicolon so that it is treated as a list by CMake - string(REPLACE "\n" ";" SKIPS_LINES ${SKIPS}) - - # For each mcu - foreach(MCU IN LISTS FAMILY_MCUS) - # For each line in only.txt - foreach(_line ${SKIPS_LINES}) - # If mcu:xxx exists for this mcu then skip - if (${_line} STREQUAL "mcu:${MCU}") - set(${RESULT} 0 PARENT_SCOPE) - return() - endif() - endforeach() - endforeach() - - # Didn't find in skip file so build - set(${RESULT} 1 PARENT_SCOPE) else() - - # Didn't find skip or only file so build + # only.txt not exist so build set(${RESULT} 1 PARENT_SCOPE) endif() endfunction() diff --git a/tools/build_utils.py b/tools/build_utils.py index 5d735bc17..b66b64b97 100644 --- a/tools/build_utils.py +++ b/tools/build_utils.py @@ -64,18 +64,19 @@ def skip_example(example, board): skip_file = ex_dir / "skip.txt" only_file = ex_dir / "only.txt" - if skip_file.exists() and only_file.exists(): - raise RuntimeError("Only have a skip or only file. Not both.") - elif skip_file.exists(): + if skip_file.exists(): skips = skip_file.read_text().split() - return ("mcu:" + mcu in skips or - "board:" + board in skips or - "family:" + family in skips) - elif only_file.exists(): + if ("mcu:" + mcu in skips or + "board:" + board in skips or + "family:" + family in skips): + return True + + if only_file.exists(): onlys = only_file.read_text().split() - return not ("mcu:" + mcu in onlys or - "board:" + board in onlys or - "family:" + family in onlys) + if not ("mcu:" + mcu in onlys or + "board:" + board in onlys or + "family:" + family in onlys): + return True return False From 802ad885ab041ecf855c1c08d97dfc45359fd1b0 Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Thu, 4 Apr 2024 17:15:38 +0700 Subject: [PATCH 228/454] minor update --- 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 28eb9aa6e..72fde1b97 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -1233,7 +1233,7 @@ bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t TU_LOG_USBD(" Queue EP %02X with %u bytes ...\r\n", ep_addr, total_bytes); #if CFG_TUD_LOG_LEVEL >= 3 - if(tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { + if(dir == TUSB_DIR_IN) { TU_LOG_MEM(CFG_TUD_LOG_LEVEL, buffer, total_bytes, 2); } #endif From 34870d34818332657e79bc5c41775f48f2debf1f Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 5 Apr 2024 00:52:23 +0700 Subject: [PATCH 229/454] update linker for lpc18, move bss to ramloc40 to have more space for .data in ramloc32 --- hw/bsp/lpc18/boards/lpcxpresso18s37/lpc1837.ld | 4 ++-- hw/bsp/lpc18/boards/mcb1800/lpc1857.ld | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/bsp/lpc18/boards/lpcxpresso18s37/lpc1837.ld b/hw/bsp/lpc18/boards/lpcxpresso18s37/lpc1837.ld index f12c1760c..f1a3add8f 100644 --- a/hw/bsp/lpc18/boards/lpcxpresso18s37/lpc1837.ld +++ b/hw/bsp/lpc18/boards/lpcxpresso18s37/lpc1837.ld @@ -296,7 +296,7 @@ SECTIONS PROVIDE(__end_bss_RamAHB_ETB16 = .) ; } > RamAHB_ETB16 AT> RamAHB_ETB16 - /* MAIN BSS SECTION */ + /* MAIN BSS SECTION: EDIT change to RamLoc40 */ .bss : ALIGN(4) { _bss = .; @@ -309,7 +309,7 @@ SECTIONS PROVIDE(__end_bss_RAM = .) ; PROVIDE(__end_bss_RamLoc32 = .) ; PROVIDE(end = .); - } > RamLoc32 AT> RamLoc32 + } > RamLoc40 AT> RamLoc40 /* > RamLoc32 AT> RamLoc32 */ /* NOINIT section for RamLoc40 */ .noinit_RAM2 (NOLOAD) : ALIGN(4) diff --git a/hw/bsp/lpc18/boards/mcb1800/lpc1857.ld b/hw/bsp/lpc18/boards/mcb1800/lpc1857.ld index 9a67e8946..837dec364 100644 --- a/hw/bsp/lpc18/boards/mcb1800/lpc1857.ld +++ b/hw/bsp/lpc18/boards/mcb1800/lpc1857.ld @@ -247,7 +247,7 @@ SECTIONS PROVIDE(__end_bss_RAM5 = .) ; } > RamAHB_ETB16 - /* MAIN BSS SECTION */ + /* MAIN BSS SECTION: EDIT change to RamLoc40 */ .bss : ALIGN(4) { _bss = .; @@ -256,7 +256,7 @@ SECTIONS . = ALIGN(4) ; _ebss = .; PROVIDE(end = .); - } > RamLoc32 + } > RamLoc40 /* RamLoc32 */ /* NOINIT section for RamLoc40 */ .noinit_RAM2 (NOLOAD) : ALIGN(4) From 34737f9c6061fdb05dfa3a9c4ddaf5f129b415d6 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 5 Apr 2024 00:55:48 +0700 Subject: [PATCH 230/454] update uvc 2ch to stream0 use yuy2, stream1 use mpeg this help reduce sram requirement for example, also provide different format (uncompressed & mpeg) --- .../video_capture/src/usb_descriptors.c | 4 +- .../device/video_capture_2ch/src/images.h | 16 +- examples/device/video_capture_2ch/src/main.c | 76 +- .../video_capture_2ch/src/usb_descriptors.c | 705 +++++++++--------- 4 files changed, 390 insertions(+), 411 deletions(-) diff --git a/examples/device/video_capture/src/usb_descriptors.c b/examples/device/video_capture/src/usb_descriptors.c index f308c75a7..5011bee18 100644 --- a/examples/device/video_capture/src/usb_descriptors.c +++ b/examples/device/video_capture/src/usb_descriptors.c @@ -56,8 +56,8 @@ char const* string_desc_arr[] = { "TinyUSB", // 1: Manufacturer "TinyUSB Device", // 2: Product NULL, // 3: Serials will use unique ID if possible - "TinyUSB UVC Control", // 4: UVC Interface - "TinyUSB UVC Streaming", // 5: UVC Interface + "UVC Control", // 4: UVC Interface + "UVC Streaming", // 5: UVC Interface }; //--------------------------------------------------------------------+ diff --git a/examples/device/video_capture_2ch/src/images.h b/examples/device/video_capture_2ch/src/images.h index ac372cb16..e5d69469e 100644 --- a/examples/device/video_capture_2ch/src/images.h +++ b/examples/device/video_capture_2ch/src/images.h @@ -1652,18 +1652,11 @@ static const unsigned char frame_buffer[128 * (96 + 1) * 2] = { 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, }; -#else +#endif + +#if 1 // mpeg compressed data (not CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) -#define color_bar_0_jpg_len 511 -#define color_bar_1_jpg_len 512 -#define color_bar_2_jpg_len 511 -#define color_bar_3_jpg_len 511 -#define color_bar_4_jpg_len 511 -#define color_bar_5_jpg_len 512 -#define color_bar_6_jpg_len 511 -#define color_bar_7_jpg_len 511 - unsigned char color_bar_0_jpg[] = { 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, @@ -1936,4 +1929,7 @@ unsigned char color_bar_7_jpg[] = { 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x47, 0xff, 0xd9 }; + + + #endif diff --git a/examples/device/video_capture_2ch/src/main.c b/examples/device/video_capture_2ch/src/main.c index 361f52b37..a373c2472 100644 --- a/examples/device/video_capture_2ch/src/main.c +++ b/examples/device/video_capture_2ch/src/main.c @@ -116,31 +116,27 @@ static unsigned frame_num[CFG_TUD_VIDEO_STREAMING] = {1}; static unsigned tx_busy = 0; static unsigned interval_ms[CFG_TUD_VIDEO_STREAMING] = {1000 / FRAME_RATE}; -#ifdef CFG_EXAMPLE_VIDEO_READONLY // For mcus that does not have enough SRAM for frame buffer, we use fixed frame data. // To further reduce the size, we use MJPEG format instead of YUY2. #include "images.h" -#if !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) static struct { uint32_t size; uint8_t const *buffer; -} const frames[] = { - {color_bar_0_jpg_len, color_bar_0_jpg}, - {color_bar_1_jpg_len, color_bar_1_jpg}, - {color_bar_2_jpg_len, color_bar_2_jpg}, - {color_bar_3_jpg_len, color_bar_3_jpg}, - {color_bar_4_jpg_len, color_bar_4_jpg}, - {color_bar_5_jpg_len, color_bar_5_jpg}, - {color_bar_6_jpg_len, color_bar_6_jpg}, - {color_bar_7_jpg_len, color_bar_7_jpg}, +} const framebuf_mjpeg[] = { + {sizeof(color_bar_0_jpg), color_bar_0_jpg}, + {sizeof(color_bar_1_jpg), color_bar_1_jpg}, + {sizeof(color_bar_2_jpg), color_bar_2_jpg}, + {sizeof(color_bar_3_jpg), color_bar_3_jpg}, + {sizeof(color_bar_4_jpg), color_bar_4_jpg}, + {sizeof(color_bar_5_jpg), color_bar_5_jpg}, + {sizeof(color_bar_6_jpg), color_bar_6_jpg}, + {sizeof(color_bar_7_jpg), color_bar_7_jpg}, }; -#endif - -#else // YUY2 frame buffer -static uint8_t frame_buffer[2][FRAME_WIDTH * FRAME_HEIGHT * 16 / 8]; +#define FRAMEBUF_SIZE (FRAME_WIDTH * FRAME_HEIGHT * 16 / 8) +static uint8_t framebuf_yuy2[FRAMEBUF_SIZE]; static void fill_color_bar(uint8_t* buffer, unsigned start_position) { /* EBU color bars: https://stackoverflow.com/questions/6939422 */ @@ -179,7 +175,26 @@ static void fill_color_bar(uint8_t* buffer, unsigned start_position) { } } -#endif +size_t get_framebuf(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, size_t fnum, void **fb) { + uint32_t idx = ctl_idx + stm_idx; + + if (idx == 0) { + // stream 0 use uncompressed YUY2 frame + fill_color_bar(framebuf_yuy2, frame_num[idx]); + *fb = framebuf_yuy2; + return FRAMEBUF_SIZE; + }else { + // stream 1 use MJPEG frame + size_t const bar_id = fnum & 0x7; + + *fb = (void*)(uintptr_t) framebuf_mjpeg[bar_id].buffer; + return framebuf_mjpeg[bar_id].size; + } +} + +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ void video_send_frame(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) { static unsigned start_ms[CFG_TUD_VIDEO_STREAMING] = {0, }; @@ -191,22 +206,16 @@ void video_send_frame(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) { frame_num[idx] = 0; return; } + void* fp; + size_t fb_size; if (!(already_sent & (1u << idx))) { already_sent |= 1u << idx; tx_busy |= 1u << idx; start_ms[idx] = board_millis(); -#ifdef CFG_EXAMPLE_VIDEO_READONLY - #if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) - tud_video_n_frame_xfer(ctl_idx, stm_idx, (void*)(uintptr_t)&frame_buffer[(frame_num[idx] % (FRAME_WIDTH / 2)) * 4], - FRAME_WIDTH * FRAME_HEIGHT * 16/8); - #else - tud_video_n_frame_xfer(ctl_idx, stm_idx, (void*)(uintptr_t)frames[frame_num[idx] % 8].buffer, frames[frame_num[idx] % 8].size); - #endif -#else - fill_color_bar(frame_buffer[idx], frame_num[idx]); - tud_video_n_frame_xfer(ctl_idx, stm_idx, (void*) frame_buffer[idx], FRAME_WIDTH * FRAME_HEIGHT * 16 / 8); -#endif + + fb_size = get_framebuf(ctl_idx, stm_idx, frame_num[idx], &fp); + tud_video_n_frame_xfer(ctl_idx, stm_idx, fp, fb_size); } unsigned cur = board_millis(); @@ -215,17 +224,8 @@ void video_send_frame(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) { start_ms[idx] += interval_ms[idx]; tx_busy |= 1u << idx; -#ifdef CFG_EXAMPLE_VIDEO_READONLY - #if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) - tud_video_n_frame_xfer(ctl_idx, stm_idx, (void*)(uintptr_t)&frame_buffer[(frame_num[idx] % (FRAME_WIDTH / 2)) * 4], - FRAME_WIDTH * FRAME_HEIGHT * 16/8); - #else - tud_video_n_frame_xfer(ctl_idx, stm_idx, (void*)(uintptr_t)frames[frame_num[idx] % 8].buffer, frames[frame_num[idx] % 8].size); - #endif -#else - fill_color_bar(frame_buffer[idx], frame_num[idx]); - tud_video_n_frame_xfer(ctl_idx, stm_idx, (void*) frame_buffer[idx], FRAME_WIDTH * FRAME_HEIGHT * 16 / 8); -#endif + fb_size = get_framebuf(ctl_idx, stm_idx, frame_num[idx], &fp); + tud_video_n_frame_xfer(ctl_idx, stm_idx, fp, fb_size); } diff --git a/examples/device/video_capture_2ch/src/usb_descriptors.c b/examples/device/video_capture_2ch/src/usb_descriptors.c index e5798f7f2..e78e452fc 100644 --- a/examples/device/video_capture_2ch/src/usb_descriptors.c +++ b/examples/device/video_capture_2ch/src/usb_descriptors.c @@ -55,13 +55,14 @@ 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 UVC Control 1", // 4: UVC Interface 1 - "TinyUSB UVC Streaming 1", // 5: UVC Interface 1 - "TinyUSB UVC Control 2", // 6: UVC Interface 2 - "TinyUSB UVC Streaming 2", // 7: UVC Interface 2 + "TinyUSB", // 1: Manufacturer + "TinyUSB Device", // 2: Product + NULL, // 3: Serials will use unique ID if possible + "UVC Control 1", // 4: UVC Interface 1 + "UVC Streaming 1", // 5: UVC Interface 1 + "UVC Control 2", // 6: UVC Interface 2 + "UVC Streaming 2", // 7: UVC Interface 2 + }; //--------------------------------------------------------------------+ @@ -140,15 +141,8 @@ typedef struct TU_ATTR_PACKED { typedef struct TU_ATTR_PACKED { tusb_desc_interface_t itf; tusb_desc_video_streaming_input_header_1byte_t header; - -#if USE_MJPEG - tusb_desc_video_format_mjpeg_t format; - tusb_desc_video_frame_mjpeg_continuous_t frame; -#else tusb_desc_video_format_uncompressed_t format; tusb_desc_video_frame_uncompressed_continuous_t frame; -#endif - tusb_desc_video_streaming_color_matching_t color; #if USE_ISO_STREAMING @@ -157,15 +151,37 @@ typedef struct TU_ATTR_PACKED { #endif tusb_desc_endpoint_t ep; -} uvc_streaming_desc_t; +} uvc_streaming_yuy2_desc_t; + +typedef struct TU_ATTR_PACKED { + tusb_desc_interface_t itf; + tusb_desc_video_streaming_input_header_1byte_t header; + tusb_desc_video_format_mjpeg_t format; + tusb_desc_video_frame_mjpeg_continuous_t frame; + tusb_desc_video_streaming_color_matching_t color; + +#if USE_ISO_STREAMING + // For ISO streaming, USB spec requires to alternate interface + tusb_desc_interface_t itf_alt; +#endif + + tusb_desc_endpoint_t ep; +} uvc_streaming_mpeg_desc_t; typedef struct TU_ATTR_PACKED { tusb_desc_configuration_t config; + struct TU_ATTR_PACKED { tusb_desc_interface_assoc_t iad; uvc_control_desc_t video_control; - uvc_streaming_desc_t video_streaming; - } uvc[2]; + uvc_streaming_yuy2_desc_t video_streaming; + } uvc_yuy2; + + struct TU_ATTR_PACKED { + tusb_desc_interface_assoc_t iad; + uvc_control_desc_t video_control; + uvc_streaming_mpeg_desc_t video_streaming; + } uvc_mpeg; } uvc_cfg_desc_t; const uvc_cfg_desc_t desc_fs_configuration = { @@ -180,369 +196,336 @@ const uvc_cfg_desc_t desc_fs_configuration = { .bmAttributes = TU_BIT(7), .bMaxPower = 100 / 2 }, - .uvc = { - { - .iad = { - .bLength = sizeof(tusb_desc_interface_assoc_t), - .bDescriptorType = TUSB_DESC_INTERFACE_ASSOCIATION, + //------------- Stream 0: YUY2 -------------// + .uvc_yuy2 = { + .iad = { + .bLength = sizeof(tusb_desc_interface_assoc_t), + .bDescriptorType = TUSB_DESC_INTERFACE_ASSOCIATION, - .bFirstInterface = ITF_NUM_VIDEO_CONTROL_1, - .bInterfaceCount = 2, - .bFunctionClass = TUSB_CLASS_VIDEO, - .bFunctionSubClass = VIDEO_SUBCLASS_INTERFACE_COLLECTION, - .bFunctionProtocol = VIDEO_ITF_PROTOCOL_UNDEFINED, - .iFunction = 0 + .bFirstInterface = ITF_NUM_VIDEO_CONTROL_1, + .bInterfaceCount = 2, + .bFunctionClass = TUSB_CLASS_VIDEO, + .bFunctionSubClass = VIDEO_SUBCLASS_INTERFACE_COLLECTION, + .bFunctionProtocol = VIDEO_ITF_PROTOCOL_UNDEFINED, + .iFunction = 0 + }, + .video_control = { + .itf = { + .bLength = sizeof(tusb_desc_interface_t), + .bDescriptorType = TUSB_DESC_INTERFACE, + + .bInterfaceNumber = ITF_NUM_VIDEO_CONTROL_1, + .bAlternateSetting = 0, + .bNumEndpoints = 0, + .bInterfaceClass = TUSB_CLASS_VIDEO, + .bInterfaceSubClass = VIDEO_SUBCLASS_CONTROL, + .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, + .iInterface = STRID_UVC_CONTROL_1 }, + .header = { + .bLength = sizeof(tusb_desc_video_control_header_1itf_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VC_HEADER, - .video_control = { - .itf = { - .bLength = sizeof(tusb_desc_interface_t), - .bDescriptorType = TUSB_DESC_INTERFACE, - - .bInterfaceNumber = ITF_NUM_VIDEO_CONTROL_1, - .bAlternateSetting = 0, - .bNumEndpoints = 0, - .bInterfaceClass = TUSB_CLASS_VIDEO, - .bInterfaceSubClass = VIDEO_SUBCLASS_CONTROL, - .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, - .iInterface = STRID_UVC_CONTROL_1 - }, - .header = { - .bLength = sizeof(tusb_desc_video_control_header_1itf_t), - .bDescriptorType = TUSB_DESC_CS_INTERFACE, - .bDescriptorSubType = VIDEO_CS_ITF_VC_HEADER, - - .bcdUVC = VIDEO_BCD_1_50, - .wTotalLength = sizeof(uvc_control_desc_t) - sizeof(tusb_desc_interface_t), // CS VC descriptors only - .dwClockFrequency = UVC_CLOCK_FREQUENCY, - .bInCollection = 1, - .baInterfaceNr = { ITF_NUM_VIDEO_STREAMING_1 } - }, - .camera_terminal = { - .bLength = sizeof(tusb_desc_video_control_camera_terminal_t), - .bDescriptorType = TUSB_DESC_CS_INTERFACE, - .bDescriptorSubType = VIDEO_CS_ITF_VC_INPUT_TERMINAL, - - .bTerminalID = UVC_ENTITY_CAP_INPUT_TERMINAL, - .wTerminalType = VIDEO_ITT_CAMERA, - .bAssocTerminal = 0, - .iTerminal = 0, - .wObjectiveFocalLengthMin = 0, - .wObjectiveFocalLengthMax = 0, - .wOcularFocalLength = 0, - .bControlSize = 3, - .bmControls = { 0, 0, 0 } - }, - .output_terminal = { - .bLength = sizeof(tusb_desc_video_control_output_terminal_t), - .bDescriptorType = TUSB_DESC_CS_INTERFACE, - .bDescriptorSubType = VIDEO_CS_ITF_VC_OUTPUT_TERMINAL, - - .bTerminalID = UVC_ENTITY_CAP_OUTPUT_TERMINAL, - .wTerminalType = VIDEO_TT_STREAMING, - .bAssocTerminal = 0, - .bSourceID = UVC_ENTITY_CAP_INPUT_TERMINAL, - .iTerminal = 0 - } + .bcdUVC = VIDEO_BCD_1_50, + .wTotalLength = sizeof(uvc_control_desc_t) - sizeof(tusb_desc_interface_t), // CS VC descriptors only + .dwClockFrequency = UVC_CLOCK_FREQUENCY, + .bInCollection = 1, + .baInterfaceNr = {ITF_NUM_VIDEO_STREAMING_1} }, + .camera_terminal = { + .bLength = sizeof(tusb_desc_video_control_camera_terminal_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VC_INPUT_TERMINAL, - .video_streaming = { - .itf = { - .bLength = sizeof(tusb_desc_interface_t), - .bDescriptorType = TUSB_DESC_INTERFACE, + .bTerminalID = UVC_ENTITY_CAP_INPUT_TERMINAL, + .wTerminalType = VIDEO_ITT_CAMERA, + .bAssocTerminal = 0, + .iTerminal = 0, + .wObjectiveFocalLengthMin = 0, + .wObjectiveFocalLengthMax = 0, + .wOcularFocalLength = 0, + .bControlSize = 3, + .bmControls = {0, 0, 0} + }, + .output_terminal = { + .bLength = sizeof(tusb_desc_video_control_output_terminal_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VC_OUTPUT_TERMINAL, - .bInterfaceNumber = ITF_NUM_VIDEO_STREAMING_1, - .bAlternateSetting = 0, - .bNumEndpoints = CFG_TUD_VIDEO_STREAMING_BULK, // bulk 1, iso 0 - .bInterfaceClass = TUSB_CLASS_VIDEO, - .bInterfaceSubClass = VIDEO_SUBCLASS_STREAMING, - .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, - .iInterface = STRID_UVC_STREAMING_1 - }, - .header = { - .bLength = sizeof(tusb_desc_video_streaming_input_header_1byte_t), - .bDescriptorType = TUSB_DESC_CS_INTERFACE, - .bDescriptorSubType = VIDEO_CS_ITF_VS_INPUT_HEADER, - - .bNumFormats = 1, - .wTotalLength = sizeof(uvc_streaming_desc_t) - sizeof(tusb_desc_interface_t) - - sizeof(tusb_desc_endpoint_t) - (USE_ISO_STREAMING ? sizeof(tusb_desc_interface_t) : 0) , // CS VS descriptors only - .bEndpointAddress = EPNUM_VIDEO_IN_1, - .bmInfo = 0, - .bTerminalLink = UVC_ENTITY_CAP_OUTPUT_TERMINAL, - .bStillCaptureMethod = 0, - .bTriggerSupport = 0, - .bTriggerUsage = 0, - .bControlSize = 1, - .bmaControls = { 0 } - }, - .format = { -#if USE_MJPEG - .bLength = sizeof(tusb_desc_video_format_mjpeg_t), - .bDescriptorType = TUSB_DESC_CS_INTERFACE, - .bDescriptorSubType = VIDEO_CS_ITF_VS_FORMAT_MJPEG, - .bFormatIndex = 1, // 1-based index - .bNumFrameDescriptors = 1, - .bmFlags = 0, -#else - .bLength = sizeof(tusb_desc_video_format_uncompressed_t), - .bDescriptorType = TUSB_DESC_CS_INTERFACE, - .bDescriptorSubType = VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED, - .bFormatIndex = 1, // 1-based index - .bNumFrameDescriptors = 1, - .guidFormat = { TUD_VIDEO_GUID_YUY2 }, - .bBitsPerPixel = 16, -#endif - .bDefaultFrameIndex = 1, - .bAspectRatioX = 0, - .bAspectRatioY = 0, - .bmInterlaceFlags = 0, - .bCopyProtect = 0 - }, - .frame = { -#if USE_MJPEG - .bLength = sizeof(tusb_desc_video_frame_mjpeg_continuous_t), - .bDescriptorType = TUSB_DESC_CS_INTERFACE, - .bDescriptorSubType = VIDEO_CS_ITF_VS_FRAME_MJPEG, -#else - .bLength = sizeof(tusb_desc_video_frame_uncompressed_continuous_t), - .bDescriptorType = TUSB_DESC_CS_INTERFACE, - .bDescriptorSubType = VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED, -#endif - .bFrameIndex = 1, // 1-based index - .bmCapabilities = 0, - .wWidth = FRAME_WIDTH, - .wHeight = FRAME_HEIGHT, - .dwMinBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * 1, - .dwMaxBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * FRAME_RATE, - .dwMaxVideoFrameBufferSize = FRAME_WIDTH * FRAME_HEIGHT * 16 / 8, - .dwDefaultFrameInterval = 10000000 / FRAME_RATE, - .bFrameIntervalType = 0, // continuous - .dwFrameInterval = { - 10000000 / FRAME_RATE, // min - 10000000, // max - 10000000 / FRAME_RATE // step - } - }, - .color = { - .bLength = sizeof(tusb_desc_video_streaming_color_matching_t), - .bDescriptorType = TUSB_DESC_CS_INTERFACE, - .bDescriptorSubType = VIDEO_CS_ITF_VS_COLORFORMAT, - - .bColorPrimaries = VIDEO_COLOR_PRIMARIES_BT709, - .bTransferCharacteristics = VIDEO_COLOR_XFER_CH_BT709, - .bMatrixCoefficients = VIDEO_COLOR_COEF_SMPTE170M - }, - -#if USE_ISO_STREAMING - .itf_alt = { - .bLength = sizeof(tusb_desc_interface_t), - .bDescriptorType = TUSB_DESC_INTERFACE, - - .bInterfaceNumber = ITF_NUM_VIDEO_STREAMING_1, - .bAlternateSetting = 1, - .bNumEndpoints = 1, - .bInterfaceClass = TUSB_CLASS_VIDEO, - .bInterfaceSubClass = VIDEO_SUBCLASS_STREAMING, - .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, - .iInterface = STRID_UVC_STREAMING_1 - }, -#endif - - .ep = { - .bLength = sizeof(tusb_desc_endpoint_t), - .bDescriptorType = TUSB_DESC_ENDPOINT, - - .bEndpointAddress = EPNUM_VIDEO_IN_1, - .bmAttributes = { - .xfer = CFG_TUD_VIDEO_STREAMING_BULK ? TUSB_XFER_BULK : TUSB_XFER_ISOCHRONOUS, - .sync = CFG_TUD_VIDEO_STREAMING_BULK ? 0 : 1 // asynchronous - }, - .wMaxPacketSize = CFG_TUD_VIDEO_STREAMING_BULK ? 64 : CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE, - .bInterval = 1 - } + .bTerminalID = UVC_ENTITY_CAP_OUTPUT_TERMINAL, + .wTerminalType = VIDEO_TT_STREAMING, + .bAssocTerminal = 0, + .bSourceID = UVC_ENTITY_CAP_INPUT_TERMINAL, + .iTerminal = 0 } }, - { - .iad = { - .bLength = sizeof(tusb_desc_interface_assoc_t), - .bDescriptorType = TUSB_DESC_INTERFACE_ASSOCIATION, - .bFirstInterface = ITF_NUM_VIDEO_CONTROL_2, - .bInterfaceCount = 2, - .bFunctionClass = TUSB_CLASS_VIDEO, - .bFunctionSubClass = VIDEO_SUBCLASS_INTERFACE_COLLECTION, - .bFunctionProtocol = VIDEO_ITF_PROTOCOL_UNDEFINED, - .iFunction = 0 + .video_streaming = { + .itf = { + .bLength = sizeof(tusb_desc_interface_t), + .bDescriptorType = TUSB_DESC_INTERFACE, + + .bInterfaceNumber = ITF_NUM_VIDEO_STREAMING_1, + .bAlternateSetting = 0, + .bNumEndpoints = CFG_TUD_VIDEO_STREAMING_BULK, // bulk 1, iso 0 + .bInterfaceClass = TUSB_CLASS_VIDEO, + .bInterfaceSubClass = VIDEO_SUBCLASS_STREAMING, + .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, + .iInterface = STRID_UVC_STREAMING_1 }, + .header = { + .bLength = sizeof(tusb_desc_video_streaming_input_header_1byte_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_INPUT_HEADER, - .video_control = { - .itf = { - .bLength = sizeof(tusb_desc_interface_t), - .bDescriptorType = TUSB_DESC_INTERFACE, - - .bInterfaceNumber = ITF_NUM_VIDEO_CONTROL_2, - .bAlternateSetting = 0, - .bNumEndpoints = 0, - .bInterfaceClass = TUSB_CLASS_VIDEO, - .bInterfaceSubClass = VIDEO_SUBCLASS_CONTROL, - .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, - .iInterface = STRID_UVC_CONTROL_2 - }, - .header = { - .bLength = sizeof(tusb_desc_video_control_header_1itf_t), - .bDescriptorType = TUSB_DESC_CS_INTERFACE, - .bDescriptorSubType = VIDEO_CS_ITF_VC_HEADER, - - .bcdUVC = VIDEO_BCD_1_50, - .wTotalLength = sizeof(uvc_control_desc_t) - sizeof(tusb_desc_interface_t), // CS VC descriptors only - .dwClockFrequency = UVC_CLOCK_FREQUENCY, - .bInCollection = 1, - .baInterfaceNr = { ITF_NUM_VIDEO_STREAMING_2 } - }, - .camera_terminal = { - .bLength = sizeof(tusb_desc_video_control_camera_terminal_t), - .bDescriptorType = TUSB_DESC_CS_INTERFACE, - .bDescriptorSubType = VIDEO_CS_ITF_VC_INPUT_TERMINAL, - - .bTerminalID = UVC_ENTITY_CAP_INPUT_TERMINAL, - .wTerminalType = VIDEO_ITT_CAMERA, - .bAssocTerminal = 0, - .iTerminal = 0, - .wObjectiveFocalLengthMin = 0, - .wObjectiveFocalLengthMax = 0, - .wOcularFocalLength = 0, - .bControlSize = 3, - .bmControls = { 0, 0, 0 } - }, - .output_terminal = { - .bLength = sizeof(tusb_desc_video_control_output_terminal_t), - .bDescriptorType = TUSB_DESC_CS_INTERFACE, - .bDescriptorSubType = VIDEO_CS_ITF_VC_OUTPUT_TERMINAL, - - .bTerminalID = UVC_ENTITY_CAP_OUTPUT_TERMINAL, - .wTerminalType = VIDEO_TT_STREAMING, - .bAssocTerminal = 0, - .bSourceID = UVC_ENTITY_CAP_INPUT_TERMINAL, - .iTerminal = 0 + .bNumFormats = 1, + .wTotalLength = sizeof(uvc_streaming_yuy2_desc_t) - sizeof(tusb_desc_interface_t) + - sizeof(tusb_desc_endpoint_t) - + (USE_ISO_STREAMING ? sizeof(tusb_desc_interface_t) : 0), // CS VS descriptors only + .bEndpointAddress = EPNUM_VIDEO_IN_1, + .bmInfo = 0, + .bTerminalLink = UVC_ENTITY_CAP_OUTPUT_TERMINAL, + .bStillCaptureMethod = 0, + .bTriggerSupport = 0, + .bTriggerUsage = 0, + .bControlSize = 1, + .bmaControls = {0} + }, + .format = { + .bLength = sizeof(tusb_desc_video_format_uncompressed_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED, + .bFormatIndex = 1, // 1-based index + .bNumFrameDescriptors = 1, + .guidFormat = {TUD_VIDEO_GUID_YUY2}, + .bBitsPerPixel = 16, + .bDefaultFrameIndex = 1, + .bAspectRatioX = 0, + .bAspectRatioY = 0, + .bmInterlaceFlags = 0, + .bCopyProtect = 0 + }, + .frame = { + .bLength = sizeof(tusb_desc_video_frame_uncompressed_continuous_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED, + .bFrameIndex = 1, // 1-based index + .bmCapabilities = 0, + .wWidth = FRAME_WIDTH, + .wHeight = FRAME_HEIGHT, + .dwMinBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * 1, + .dwMaxBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * FRAME_RATE, + .dwMaxVideoFrameBufferSize = FRAME_WIDTH * FRAME_HEIGHT * 16 / 8, + .dwDefaultFrameInterval = 10000000 / FRAME_RATE, + .bFrameIntervalType = 0, // continuous + .dwFrameInterval = { + 10000000 / FRAME_RATE, // min + 10000000, // max + 10000000 / FRAME_RATE // step } }, + .color = { + .bLength = sizeof(tusb_desc_video_streaming_color_matching_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_COLORFORMAT, - .video_streaming = { - .itf = { - .bLength = sizeof(tusb_desc_interface_t), - .bDescriptorType = TUSB_DESC_INTERFACE, - - .bInterfaceNumber = ITF_NUM_VIDEO_STREAMING_2, - .bAlternateSetting = 0, - .bNumEndpoints = CFG_TUD_VIDEO_STREAMING_BULK, // bulk 1, iso 0 - .bInterfaceClass = TUSB_CLASS_VIDEO, - .bInterfaceSubClass = VIDEO_SUBCLASS_STREAMING, - .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, - .iInterface = STRID_UVC_STREAMING_2 - }, - .header = { - .bLength = sizeof(tusb_desc_video_streaming_input_header_1byte_t), - .bDescriptorType = TUSB_DESC_CS_INTERFACE, - .bDescriptorSubType = VIDEO_CS_ITF_VS_INPUT_HEADER, - - .bNumFormats = 1, - .wTotalLength = sizeof(uvc_streaming_desc_t) - sizeof(tusb_desc_interface_t) - - sizeof(tusb_desc_endpoint_t) - (USE_ISO_STREAMING ? sizeof(tusb_desc_interface_t) : 0) , // CS VS descriptors only - .bEndpointAddress = EPNUM_VIDEO_IN_2, - .bmInfo = 0, - .bTerminalLink = UVC_ENTITY_CAP_OUTPUT_TERMINAL, - .bStillCaptureMethod = 0, - .bTriggerSupport = 0, - .bTriggerUsage = 0, - .bControlSize = 1, - .bmaControls = { 0 } - }, - .format = { -#if USE_MJPEG - .bLength = sizeof(tusb_desc_video_format_mjpeg_t), - .bDescriptorType = TUSB_DESC_CS_INTERFACE, - .bDescriptorSubType = VIDEO_CS_ITF_VS_FORMAT_MJPEG, - .bFormatIndex = 1, // 1-based index - .bNumFrameDescriptors = 1, - .bmFlags = 0, -#else - .bLength = sizeof(tusb_desc_video_format_uncompressed_t), - .bDescriptorType = TUSB_DESC_CS_INTERFACE, - .bDescriptorSubType = VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED, - .bFormatIndex = 1, // 1-based index - .bNumFrameDescriptors = 1, - .guidFormat = { TUD_VIDEO_GUID_YUY2 }, - .bBitsPerPixel = 16, -#endif - .bDefaultFrameIndex = 1, - .bAspectRatioX = 0, - .bAspectRatioY = 0, - .bmInterlaceFlags = 0, - .bCopyProtect = 0 - }, - .frame = { -#if USE_MJPEG - .bLength = sizeof(tusb_desc_video_frame_mjpeg_continuous_t), - .bDescriptorType = TUSB_DESC_CS_INTERFACE, - .bDescriptorSubType = VIDEO_CS_ITF_VS_FRAME_MJPEG, -#else - .bLength = sizeof(tusb_desc_video_frame_uncompressed_continuous_t), - .bDescriptorType = TUSB_DESC_CS_INTERFACE, - .bDescriptorSubType = VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED, -#endif - .bFrameIndex = 1, // 1-based index - .bmCapabilities = 0, - .wWidth = FRAME_WIDTH, - .wHeight = FRAME_HEIGHT, - .dwMinBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * 1, - .dwMaxBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * FRAME_RATE, - .dwMaxVideoFrameBufferSize = FRAME_WIDTH * FRAME_HEIGHT * 16 / 8, - .dwDefaultFrameInterval = 10000000 / FRAME_RATE, - .bFrameIntervalType = 0, // continuous - .dwFrameInterval = { - 10000000 / FRAME_RATE, // min - 10000000, // max - 10000000 / FRAME_RATE // step - } - }, - .color = { - .bLength = sizeof(tusb_desc_video_streaming_color_matching_t), - .bDescriptorType = TUSB_DESC_CS_INTERFACE, - .bDescriptorSubType = VIDEO_CS_ITF_VS_COLORFORMAT, - - .bColorPrimaries = VIDEO_COLOR_PRIMARIES_BT709, - .bTransferCharacteristics = VIDEO_COLOR_XFER_CH_BT709, - .bMatrixCoefficients = VIDEO_COLOR_COEF_SMPTE170M - }, + .bColorPrimaries = VIDEO_COLOR_PRIMARIES_BT709, + .bTransferCharacteristics = VIDEO_COLOR_XFER_CH_BT709, + .bMatrixCoefficients = VIDEO_COLOR_COEF_SMPTE170M + }, #if USE_ISO_STREAMING - .itf_alt = { - .bLength = sizeof(tusb_desc_interface_t), - .bDescriptorType = TUSB_DESC_INTERFACE, + .itf_alt = { + .bLength = sizeof(tusb_desc_interface_t), + .bDescriptorType = TUSB_DESC_INTERFACE, - .bInterfaceNumber = ITF_NUM_VIDEO_STREAMING_2, - .bAlternateSetting = 1, - .bNumEndpoints = 1, - .bInterfaceClass = TUSB_CLASS_VIDEO, - .bInterfaceSubClass = VIDEO_SUBCLASS_STREAMING, - .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, - .iInterface = STRID_UVC_STREAMING_2 - }, + .bInterfaceNumber = ITF_NUM_VIDEO_STREAMING_1, + .bAlternateSetting = 1, + .bNumEndpoints = 1, + .bInterfaceClass = TUSB_CLASS_VIDEO, + .bInterfaceSubClass = VIDEO_SUBCLASS_STREAMING, + .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, + .iInterface = STRID_UVC_STREAMING_1 + }, #endif + .ep = { + .bLength = sizeof(tusb_desc_endpoint_t), + .bDescriptorType = TUSB_DESC_ENDPOINT, - .ep = { - .bLength = sizeof(tusb_desc_endpoint_t), - .bDescriptorType = TUSB_DESC_ENDPOINT, + .bEndpointAddress = EPNUM_VIDEO_IN_1, + .bmAttributes = { + .xfer = CFG_TUD_VIDEO_STREAMING_BULK ? TUSB_XFER_BULK : TUSB_XFER_ISOCHRONOUS, + .sync = CFG_TUD_VIDEO_STREAMING_BULK ? 0 : 1 // asynchronous + }, + .wMaxPacketSize = CFG_TUD_VIDEO_STREAMING_BULK ? 64 : CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE, + .bInterval = 1 + } + } + }, + //------------- Stream 1: MPEG -------------// + .uvc_mpeg = { + .iad = { + .bLength = sizeof(tusb_desc_interface_assoc_t), + .bDescriptorType = TUSB_DESC_INTERFACE_ASSOCIATION, - .bEndpointAddress = EPNUM_VIDEO_IN_2, - .bmAttributes = { - .xfer = CFG_TUD_VIDEO_STREAMING_BULK ? TUSB_XFER_BULK : TUSB_XFER_ISOCHRONOUS, - .sync = CFG_TUD_VIDEO_STREAMING_BULK ? 0 : 1 // asynchronous - }, - .wMaxPacketSize = CFG_TUD_VIDEO_STREAMING_BULK ? 64 : CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE, - .bInterval = 1 + .bFirstInterface = ITF_NUM_VIDEO_CONTROL_2, + .bInterfaceCount = 2, + .bFunctionClass = TUSB_CLASS_VIDEO, + .bFunctionSubClass = VIDEO_SUBCLASS_INTERFACE_COLLECTION, + .bFunctionProtocol = VIDEO_ITF_PROTOCOL_UNDEFINED, + .iFunction = 0 + }, + + .video_control = { + .itf = { + .bLength = sizeof(tusb_desc_interface_t), + .bDescriptorType = TUSB_DESC_INTERFACE, + + .bInterfaceNumber = ITF_NUM_VIDEO_CONTROL_2, + .bAlternateSetting = 0, + .bNumEndpoints = 0, + .bInterfaceClass = TUSB_CLASS_VIDEO, + .bInterfaceSubClass = VIDEO_SUBCLASS_CONTROL, + .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, + .iInterface = STRID_UVC_CONTROL_2 + }, + .header = { + .bLength = sizeof(tusb_desc_video_control_header_1itf_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VC_HEADER, + + .bcdUVC = VIDEO_BCD_1_50, + .wTotalLength = sizeof(uvc_control_desc_t) - sizeof(tusb_desc_interface_t), // CS VC descriptors only + .dwClockFrequency = UVC_CLOCK_FREQUENCY, + .bInCollection = 1, + .baInterfaceNr = { ITF_NUM_VIDEO_STREAMING_2 } + }, + .camera_terminal = { + .bLength = sizeof(tusb_desc_video_control_camera_terminal_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VC_INPUT_TERMINAL, + + .bTerminalID = UVC_ENTITY_CAP_INPUT_TERMINAL, + .wTerminalType = VIDEO_ITT_CAMERA, + .bAssocTerminal = 0, + .iTerminal = 0, + .wObjectiveFocalLengthMin = 0, + .wObjectiveFocalLengthMax = 0, + .wOcularFocalLength = 0, + .bControlSize = 3, + .bmControls = { 0, 0, 0 } + }, + .output_terminal = { + .bLength = sizeof(tusb_desc_video_control_output_terminal_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VC_OUTPUT_TERMINAL, + + .bTerminalID = UVC_ENTITY_CAP_OUTPUT_TERMINAL, + .wTerminalType = VIDEO_TT_STREAMING, + .bAssocTerminal = 0, + .bSourceID = UVC_ENTITY_CAP_INPUT_TERMINAL, + .iTerminal = 0 + } + }, + + .video_streaming = { + .itf = { + .bLength = sizeof(tusb_desc_interface_t), + .bDescriptorType = TUSB_DESC_INTERFACE, + + .bInterfaceNumber = ITF_NUM_VIDEO_STREAMING_2, + .bAlternateSetting = 0, + .bNumEndpoints = CFG_TUD_VIDEO_STREAMING_BULK, // bulk 1, iso 0 + .bInterfaceClass = TUSB_CLASS_VIDEO, + .bInterfaceSubClass = VIDEO_SUBCLASS_STREAMING, + .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, + .iInterface = STRID_UVC_STREAMING_2 + }, + .header = { + .bLength = sizeof(tusb_desc_video_streaming_input_header_1byte_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_INPUT_HEADER, + + .bNumFormats = 1, + .wTotalLength = sizeof(uvc_streaming_mpeg_desc_t) - sizeof(tusb_desc_interface_t) + - sizeof(tusb_desc_endpoint_t) - (USE_ISO_STREAMING ? sizeof(tusb_desc_interface_t) : 0) , // CS VS descriptors only + .bEndpointAddress = EPNUM_VIDEO_IN_2, + .bmInfo = 0, + .bTerminalLink = UVC_ENTITY_CAP_OUTPUT_TERMINAL, + .bStillCaptureMethod = 0, + .bTriggerSupport = 0, + .bTriggerUsage = 0, + .bControlSize = 1, + .bmaControls = { 0 } + }, + .format = { + .bLength = sizeof(tusb_desc_video_format_mjpeg_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_FORMAT_MJPEG, + .bFormatIndex = 1, // 1-based index + .bNumFrameDescriptors = 1, + .bmFlags = 0, + .bDefaultFrameIndex = 1, + .bAspectRatioX = 0, + .bAspectRatioY = 0, + .bmInterlaceFlags = 0, + .bCopyProtect = 0 + }, + .frame = { + .bLength = sizeof(tusb_desc_video_frame_mjpeg_continuous_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_FRAME_MJPEG, + .bFrameIndex = 1, // 1-based index + .bmCapabilities = 0, + .wWidth = FRAME_WIDTH, + .wHeight = FRAME_HEIGHT, + .dwMinBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * 1, + .dwMaxBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * FRAME_RATE, + .dwMaxVideoFrameBufferSize = FRAME_WIDTH * FRAME_HEIGHT * 16 / 8, + .dwDefaultFrameInterval = 10000000 / FRAME_RATE, + .bFrameIntervalType = 0, // continuous + .dwFrameInterval = { + 10000000 / FRAME_RATE, // min + 10000000, // max + 10000000 / FRAME_RATE // step } + }, + .color = { + .bLength = sizeof(tusb_desc_video_streaming_color_matching_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_COLORFORMAT, + + .bColorPrimaries = VIDEO_COLOR_PRIMARIES_BT709, + .bTransferCharacteristics = VIDEO_COLOR_XFER_CH_BT709, + .bMatrixCoefficients = VIDEO_COLOR_COEF_SMPTE170M + }, + +#if USE_ISO_STREAMING + .itf_alt = { + .bLength = sizeof(tusb_desc_interface_t), + .bDescriptorType = TUSB_DESC_INTERFACE, + + .bInterfaceNumber = ITF_NUM_VIDEO_STREAMING_2, + .bAlternateSetting = 1, + .bNumEndpoints = 1, + .bInterfaceClass = TUSB_CLASS_VIDEO, + .bInterfaceSubClass = VIDEO_SUBCLASS_STREAMING, + .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, + .iInterface = STRID_UVC_STREAMING_2 + }, +#endif + .ep = { + .bLength = sizeof(tusb_desc_endpoint_t), + .bDescriptorType = TUSB_DESC_ENDPOINT, + + .bEndpointAddress = EPNUM_VIDEO_IN_2, + .bmAttributes = { + .xfer = CFG_TUD_VIDEO_STREAMING_BULK ? TUSB_XFER_BULK : TUSB_XFER_ISOCHRONOUS, + .sync = CFG_TUD_VIDEO_STREAMING_BULK ? 0 : 1 // asynchronous + }, + .wMaxPacketSize = CFG_TUD_VIDEO_STREAMING_BULK ? 64 : CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE, + .bInterval = 1 } } } @@ -558,8 +541,8 @@ static uint8_t * get_hs_configuration_desc(void) { desc_hs_configuration = desc_fs_configuration; // change endpoint bulk size to 512 if bulk streaming if (CFG_TUD_VIDEO_STREAMING_BULK) { - desc_hs_configuration.uvc[0].video_streaming.ep.wMaxPacketSize = 512; - desc_hs_configuration.uvc[1].video_streaming.ep.wMaxPacketSize = 512; + desc_hs_configuration.uvc_yuy2.video_streaming.ep.wMaxPacketSize = 512; + desc_hs_configuration.uvc_mpeg.video_streaming.ep.wMaxPacketSize = 512; } } init = true; From df1f84adad8090066ccb7393791c70f752c9af4e Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 5 Apr 2024 13:12:58 +0700 Subject: [PATCH 231/454] change .bss section from ramloc32 to ramloc40 for lpc43xx --- hw/bsp/lpc43/boards/ea4357/lpc4357.ld | 4 ++-- hw/bsp/lpc43/boards/lpcxpresso43s67/lpc4367.ld | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/bsp/lpc43/boards/ea4357/lpc4357.ld b/hw/bsp/lpc43/boards/ea4357/lpc4357.ld index e3dfbfda1..53343f6a9 100644 --- a/hw/bsp/lpc43/boards/ea4357/lpc4357.ld +++ b/hw/bsp/lpc43/boards/ea4357/lpc4357.ld @@ -248,7 +248,7 @@ SECTIONS PROVIDE(__end_bss_RAM5 = .) ; } > RamAHB_ETB16 - /* MAIN BSS SECTION */ + /* MAIN BSS SECTION: EDIT change to RamLoc40 */ .bss : ALIGN(4) { _bss = .; @@ -257,7 +257,7 @@ SECTIONS . = ALIGN(4) ; _ebss = .; PROVIDE(end = .); - } > RamLoc32 + } > RamLoc40 /* RamLoc32 */ /* NOINIT section for RamLoc40 */ .noinit_RAM2 (NOLOAD) : ALIGN(4) diff --git a/hw/bsp/lpc43/boards/lpcxpresso43s67/lpc4367.ld b/hw/bsp/lpc43/boards/lpcxpresso43s67/lpc4367.ld index c03149b8b..99276fb47 100644 --- a/hw/bsp/lpc43/boards/lpcxpresso43s67/lpc4367.ld +++ b/hw/bsp/lpc43/boards/lpcxpresso43s67/lpc4367.ld @@ -292,7 +292,7 @@ SECTIONS PROVIDE(__end_bss_RamAHB_ETB16 = .) ; } > RamAHB_ETB16 AT> RamAHB_ETB16 - /* MAIN BSS SECTION */ + /* MAIN BSS SECTION: EDIT change to RamLoc40 */ .bss : ALIGN(4) { _bss = .; @@ -305,7 +305,7 @@ SECTIONS PROVIDE(__end_bss_RAM = .) ; PROVIDE(__end_bss_RamLoc32 = .) ; PROVIDE(end = .); - } > RamLoc32 AT> RamLoc32 + } > RamLoc40 AT> RamLoc40 /* > RamLoc32 AT> RamLoc32 */ /* NOINIT section for RamLoc40 */ .noinit_RAM2 (NOLOAD) : ALIGN(4) From 5b2441d8a3cae01de522d28cbac378464d3df678 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 5 Apr 2024 16:12:31 +0700 Subject: [PATCH 232/454] support CFG_EXAMPLE_VIDEO_READONLY for stream0 for small mcu --- examples/device/video_capture_2ch/src/images.h | 17 ++++++++--------- examples/device/video_capture_2ch/src/main.c | 10 +++++++++- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/examples/device/video_capture_2ch/src/images.h b/examples/device/video_capture_2ch/src/images.h index e5d69469e..f0badd074 100644 --- a/examples/device/video_capture_2ch/src/images.h +++ b/examples/device/video_capture_2ch/src/images.h @@ -1,6 +1,8 @@ -#if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) -// uncopmressed frame -static const unsigned char frame_buffer[128 * (96 + 1) * 2] = { +#if defined(CFG_EXAMPLE_VIDEO_READONLY) +//--------------------------------------------------------------------+ +// YUY2 Uncompressed Frame (fixed) +//--------------------------------------------------------------------+ +static const unsigned char framebuf_yuy2_readonly[128 * (96 + 1) * 2] = { /* 0 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, @@ -1654,9 +1656,10 @@ static const unsigned char frame_buffer[128 * (96 + 1) * 2] = { #endif -#if 1 +//--------------------------------------------------------------------+ +// MPEG Compressed Frame (fixed) +//--------------------------------------------------------------------+ -// mpeg compressed data (not CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) unsigned char color_bar_0_jpg[] = { 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, @@ -1929,7 +1932,3 @@ unsigned char color_bar_7_jpg[] = { 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x47, 0xff, 0xd9 }; - - - -#endif diff --git a/examples/device/video_capture_2ch/src/main.c b/examples/device/video_capture_2ch/src/main.c index a373c2472..82bc7d6ca 100644 --- a/examples/device/video_capture_2ch/src/main.c +++ b/examples/device/video_capture_2ch/src/main.c @@ -112,6 +112,8 @@ void tud_resume_cb(void) { //--------------------------------------------------------------------+ // USB Video //--------------------------------------------------------------------+ +#define FRAMEBUF_SIZE (FRAME_WIDTH * FRAME_HEIGHT * 16 / 8) + static unsigned frame_num[CFG_TUD_VIDEO_STREAMING] = {1}; static unsigned tx_busy = 0; static unsigned interval_ms[CFG_TUD_VIDEO_STREAMING] = {1000 / FRAME_RATE}; @@ -134,8 +136,8 @@ static struct { {sizeof(color_bar_7_jpg), color_bar_7_jpg}, }; +#if !defined(CFG_EXAMPLE_VIDEO_READONLY) // YUY2 frame buffer -#define FRAMEBUF_SIZE (FRAME_WIDTH * FRAME_HEIGHT * 16 / 8) static uint8_t framebuf_yuy2[FRAMEBUF_SIZE]; static void fill_color_bar(uint8_t* buffer, unsigned start_position) { @@ -174,14 +176,20 @@ static void fill_color_bar(uint8_t* buffer, unsigned start_position) { p += FRAME_WIDTH * 2; } } +#endif size_t get_framebuf(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, size_t fnum, void **fb) { uint32_t idx = ctl_idx + stm_idx; if (idx == 0) { // stream 0 use uncompressed YUY2 frame + #if defined(CFG_EXAMPLE_VIDEO_READONLY) + *fb = (void*)(uintptr_t ) framebuf_yuy2_readonly[(fnum % (FRAME_WIDTH / 2)) * 4]; + #else fill_color_bar(framebuf_yuy2, frame_num[idx]); *fb = framebuf_yuy2; + #endif + return FRAMEBUF_SIZE; }else { // stream 1 use MJPEG frame From 2f9700dc2b5dd758b9da7b283a03aa311e2f9883 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 5 Apr 2024 16:28:17 +0700 Subject: [PATCH 233/454] fix ram overflow with ram41 --- hw/bsp/ra/boards/ra4m1_ek/board.cmake | 4 +++- hw/bsp/ra/boards/uno_r4/board.cmake | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/hw/bsp/ra/boards/ra4m1_ek/board.cmake b/hw/bsp/ra/boards/ra4m1_ek/board.cmake index 4188d3188..7bb48bf44 100644 --- a/hw/bsp/ra/boards/ra4m1_ek/board.cmake +++ b/hw/bsp/ra/boards/ra4m1_ek/board.cmake @@ -4,7 +4,9 @@ set(MCU_VARIANT ra4m1) set(JLINK_DEVICE R7FA4M1AB) function(update_board TARGET) -# target_compile_definitions(${TARGET} PUBLIC) + target_compile_definitions(${TARGET} PUBLIC + CFG_EXAMPLE_VIDEO_READONLY + ) # target_sources(${TARGET} PRIVATE) # target_include_directories(${BOARD_TARGET} PUBLIC) endfunction() diff --git a/hw/bsp/ra/boards/uno_r4/board.cmake b/hw/bsp/ra/boards/uno_r4/board.cmake index 34780d776..9d59bc4f7 100644 --- a/hw/bsp/ra/boards/uno_r4/board.cmake +++ b/hw/bsp/ra/boards/uno_r4/board.cmake @@ -5,7 +5,9 @@ set(JLINK_DEVICE R7FA4M1AB) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) function(update_board TARGET) -# target_compile_definitions(${TARGET} PUBLIC) + target_compile_definitions(${TARGET} PUBLIC + CFG_EXAMPLE_VIDEO_READONLY + ) # target_sources(${TARGET} PRIVATE) # target_include_directories(${BOARD_TARGET} PUBLIC) endfunction() From caf2c5e0b75b72c0b0357ca364a76d70b5846bde Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 5 Apr 2024 17:04:33 +0700 Subject: [PATCH 234/454] reverted un-related file changes --- examples/device/cdc_msc_freertos/src/main.c | 51 ++++++++++--------- .../boards/frdm_k32l2a4s/board.mk | 3 -- .../kinetis_k32l2/boards/frdm_k32l2b/board.mk | 3 -- hw/bsp/nrf/boards/pca10095/board.h | 4 +- hw/bsp/nrf/boards/pca10095/board.mk | 3 ++ hw/bsp/nrf/family.c | 1 + src/class/msc/msc_device.c | 2 +- src/class/video/video.h | 6 ++- src/common/tusb_debug.h | 3 +- src/common/tusb_fifo.c | 1 + src/host/usbh_pvt.h | 6 ++- src/portable/nordic/nrf5x/dcd_nrf5x.c | 8 ++- src/portable/ohci/ohci.h | 2 +- 13 files changed, 54 insertions(+), 39 deletions(-) diff --git a/examples/device/cdc_msc_freertos/src/main.c b/examples/device/cdc_msc_freertos/src/main.c index 1dadc4513..e94e8eaec 100644 --- a/examples/device/cdc_msc_freertos/src/main.c +++ b/examples/device/cdc_msc_freertos/src/main.c @@ -52,7 +52,8 @@ #define USBD_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1) #endif -#define CDC_STACK_SZIE configMINIMAL_STACK_SIZE +#define CDC_STACK_SIZE configMINIMAL_STACK_SIZE +#define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTOTYPES @@ -69,21 +70,22 @@ enum { BLINK_SUSPENDED = 2500, }; -// static timer & task +// static task #if configSUPPORT_STATIC_ALLOCATION -StaticTimer_t blinky_tmdef; +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 cdc_stack[CDC_STACK_SZIE]; +StackType_t cdc_stack[CDC_STACK_SIZE]; StaticTask_t cdc_taskdef; #endif -TimerHandle_t blinky_tm; +static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; -static void led_blinky_cb(TimerHandle_t xTimer); static void usb_device_task(void *param); +void led_blinking_task(void* param); void cdc_task(void *params); //--------------------------------------------------------------------+ @@ -94,22 +96,20 @@ int main(void) { board_init(); #if configSUPPORT_STATIC_ALLOCATION - // soft timer for blinky - blinky_tm = xTimerCreateStatic(NULL, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), true, NULL, led_blinky_cb, &blinky_tmdef); + // 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 CDC task - xTaskCreateStatic(cdc_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES-2, cdc_stack, &cdc_taskdef); + xTaskCreateStatic(cdc_task, "cdc", CDC_STACK_SIZE, NULL, configMAX_PRIORITIES - 2, cdc_stack, &cdc_taskdef); #else - blinky_tm = xTimerCreate(NULL, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), true, NULL, led_blinky_cb); + 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(cdc_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES - 2, NULL); #endif - 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) vTaskStartScheduler(); @@ -154,12 +154,12 @@ static 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 @@ -167,16 +167,12 @@ void tud_umount_cb(void) { // 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); + blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed void tud_resume_cb(void) { - if (tud_mounted()) { - xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_MOUNTED), 0); - } else { - xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), 0); - } + blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ @@ -235,10 +231,17 @@ void tud_cdc_rx_cb(uint8_t itf) { //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ -static 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/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/board.mk b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/board.mk index f69700139..c4dc65b63 100644 --- a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/board.mk +++ b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/board.mk @@ -8,9 +8,6 @@ CFLAGS += -Wno-error=unused-parameter -Wno-error=redundant-decls -Wno-error=cast # All source paths should be relative to the top level. LD_FILE = $(MCU_DIR)/gcc/K32L2A41xxxxA_flash.ld -SRC_C += \ - $(MCU_DIR)/project_template/clock_config.c \ - # For flash-jlink target JLINK_DEVICE = K32L2A41xxxxA diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.mk b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.mk index 82456b721..9cf36c500 100644 --- a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.mk +++ b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.mk @@ -8,9 +8,6 @@ CFLAGS += -Wno-error=unused-parameter -Wno-error=redundant-decls # All source paths should be relative to the top level. LD_FILE = $(MCU_DIR)/gcc/K32L2B31xxxxA_flash.ld -SRC_C += \ - $(MCU_DIR)/project_template/clock_config.c \ - # For flash-jlink target JLINK_DEVICE = K32L2B31xxxxA diff --git a/hw/bsp/nrf/boards/pca10095/board.h b/hw/bsp/nrf/boards/pca10095/board.h index 2a46e5422..846c2ee5b 100644 --- a/hw/bsp/nrf/boards/pca10095/board.h +++ b/hw/bsp/nrf/boards/pca10095/board.h @@ -42,8 +42,8 @@ #define BUTTON_STATE_ACTIVE 0 // UART -#define UART_RX_PIN 32 -#define UART_TX_PIN 33 +#define UART_RX_PIN 22 +#define UART_TX_PIN 20 // SPI for USB host shield // Pin is correct but not working probably due to signal incompatible (1.8V 3v3) with MAC3421E !? diff --git a/hw/bsp/nrf/boards/pca10095/board.mk b/hw/bsp/nrf/boards/pca10095/board.mk index 9c4edbafc..20580d619 100644 --- a/hw/bsp/nrf/boards/pca10095/board.mk +++ b/hw/bsp/nrf/boards/pca10095/board.mk @@ -2,6 +2,9 @@ CPU_CORE = cortex-m33 MCU_VARIANT = nrf5340_application CFLAGS += -DNRF5340_XXAA -DNRF5340_XXAA_APPLICATION +# enable max3421 host driver for this board +MAX3421_HOST = 1 + LD_FILE = hw/mcu/nordic/nrfx/mdk/nrf5340_xxaa_application.ld SRC_C += hw/mcu/nordic/nrfx/drivers/src/nrfx_usbreg.c diff --git a/hw/bsp/nrf/family.c b/hw/bsp/nrf/family.c index d6bb2d868..71c651f5f 100644 --- a/hw/bsp/nrf/family.c +++ b/hw/bsp/nrf/family.c @@ -76,6 +76,7 @@ enum { #define LFCLK_SRC_RC CLOCK_LFCLKSRC_SRC_LFRC #define VBUSDETECT_Msk USBREG_USBREGSTATUS_VBUSDETECT_Msk #define OUTPUTRDY_Msk USBREG_USBREGSTATUS_OUTPUTRDY_Msk + #define GPIOTE_IRQn GPIOTE1_IRQn #else #define LFCLK_SRC_RC CLOCK_LFCLKSRC_SRC_RC #define VBUSDETECT_Msk POWER_USBREGSTATUS_VBUSDETECT_Msk diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index 2589dcd2c..c145d86a6 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -203,7 +203,7 @@ uint8_t rdwr10_validate_cmd(msc_cbw_t const* cbw) //--------------------------------------------------------------------+ // Debug //--------------------------------------------------------------------+ -#if CFG_TUSB_DEBUG >= 2 +#if CFG_TUSB_DEBUG >= CFG_TUD_MSC_LOG_LEVEL TU_ATTR_UNUSED tu_static tu_lookup_entry_t const _msc_scsi_cmd_lookup[] = { diff --git a/src/class/video/video.h b/src/class/video/video.h index 3b511af96..b8a9b6369 100644 --- a/src/class/video/video.h +++ b/src/class/video/video.h @@ -369,6 +369,8 @@ typedef struct TU_ATTR_PACKED { uint8_t bCopyProtect; } tusb_desc_video_format_uncompressed_t; +TU_VERIFY_STATIC(sizeof(tusb_desc_video_format_uncompressed_t) == 27, "size is not correct"); + // Uncompressed payload specs: 3.1.2 frame descriptor #define tusb_desc_video_frame_uncompressed_nint_t(_nint) \ struct TU_ATTR_PACKED { \ @@ -382,7 +384,7 @@ typedef struct TU_ATTR_PACKED { uint32_t dwMinBitRate; \ uint32_t dwMaxBitRate; \ uint32_t dwMaxVideoFrameBufferSize; /* deprecated in 1.5 */ \ - uint32_t dwDefaultFrameInterval; \ + uint32_t dwDefaultFrameInterval; /* 100ns unit */\ uint8_t bFrameIntervalType; \ uint32_t dwFrameInterval[_nint]; \ } @@ -414,6 +416,8 @@ typedef struct TU_ATTR_PACKED { uint8_t bCopyProtect; } tusb_desc_video_format_mjpeg_t; +TU_VERIFY_STATIC(sizeof(tusb_desc_video_format_mjpeg_t) == 11, "size is not correct"); + // MJPEG payload specs: 3.1.2 frame descriptor (same as uncompressed) typedef tusb_desc_video_frame_uncompressed_t tusb_desc_video_frame_mjpeg_t; typedef tusb_desc_video_frame_uncompressed_1int_t tusb_desc_video_frame_mjpeg_1int_t; diff --git a/src/common/tusb_debug.h b/src/common/tusb_debug.h index 0f4dc93f3..2e9f1d9cd 100644 --- a/src/common/tusb_debug.h +++ b/src/common/tusb_debug.h @@ -60,6 +60,7 @@ void tu_print_mem(void const *buf, uint32_t count, uint8_t indent); static inline void tu_print_buf(uint8_t const* buf, uint32_t bufsize) { for(uint32_t i=0; i= 2 diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index d6c3db4ce..76696396b 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -224,6 +224,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; + default: break; } } diff --git a/src/host/usbh_pvt.h b/src/host/usbh_pvt.h index 46d13a907..95de915e9 100644 --- a/src/host/usbh_pvt.h +++ b/src/host/usbh_pvt.h @@ -35,7 +35,11 @@ extern "C" { #endif -#define TU_LOG_USBH(...) TU_LOG(CFG_TUH_LOG_LEVEL, __VA_ARGS__) +#define TU_LOG_USBH(...) TU_LOG(CFG_TUH_LOG_LEVEL, __VA_ARGS__) +#define TU_LOG_MEM_USBH(...) TU_LOG_MEM(CFG_TUH_LOG_LEVEL, __VA_ARGS__) +#define TU_LOG_BUF_USBH(...) TU_LOG_BUF(CFG_TUH_LOG_LEVEL, __VA_ARGS__) +#define TU_LOG_INT_USBH(...) TU_LOG_INT(CFG_TUH_LOG_LEVEL, __VA_ARGS__) +#define TU_LOG_HEX_USBH(...) TU_LOG_HEX(CFG_TUH_LOG_LEVEL, __VA_ARGS__) enum { USBH_EPSIZE_BULK_MAX = (TUH_OPT_HIGH_SPEED ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS) diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index cf9e5923b..80a285ef0 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -653,7 +653,11 @@ void dcd_int_handler(uint8_t rhport) if (NRF_USBD->EPOUTEN & USBD_EPOUTEN_ISOOUT_Msk) { iso_enabled = true; - xact_out_dma(EP_ISO_NUM); + // Transfer from endpoint to RAM only if data is not corrupted + if ((int_status & USBD_INTEN_USBEVENT_Msk) == 0 || + (NRF_USBD->EVENTCAUSE & USBD_EVENTCAUSE_ISOOUTCRC_Msk) == 0) { + xact_out_dma(EP_ISO_NUM); + } } // ISOIN: Notify client that data was transferred @@ -683,7 +687,7 @@ void dcd_int_handler(uint8_t rhport) { TU_LOG(3, "EVENTCAUSE = 0x%04lX\r\n", NRF_USBD->EVENTCAUSE); - enum { EVT_CAUSE_MASK = USBD_EVENTCAUSE_SUSPEND_Msk | USBD_EVENTCAUSE_RESUME_Msk | USBD_EVENTCAUSE_USBWUALLOWED_Msk }; + enum { EVT_CAUSE_MASK = USBD_EVENTCAUSE_SUSPEND_Msk | USBD_EVENTCAUSE_RESUME_Msk | USBD_EVENTCAUSE_USBWUALLOWED_Msk | USBD_EVENTCAUSE_ISOOUTCRC_Msk }; uint32_t const evt_cause = NRF_USBD->EVENTCAUSE & EVT_CAUSE_MASK; NRF_USBD->EVENTCAUSE = evt_cause; // clear interrupt diff --git a/src/portable/ohci/ohci.h b/src/portable/ohci/ohci.h index 4feefd771..94bad5df7 100644 --- a/src/portable/ohci/ohci.h +++ b/src/portable/ohci/ohci.h @@ -83,7 +83,7 @@ typedef struct TU_ATTR_ALIGNED(16) volatile uint32_t condition_code : 4; // Word 1 - volatile uint8_t* current_buffer_pointer; + uint8_t* volatile current_buffer_pointer; // Word 2 : next TD volatile uint32_t next; From 7fff83086f95d9bcc0e5c8a6a9ea0cf7202cbe38 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 5 Apr 2024 17:08:22 +0700 Subject: [PATCH 235/454] more reverted changes --- .../boards/frdm_k32l2a4s/clock_config.c | 491 ++++++++++++++++++ .../boards/frdm_k32l2b/clock_config.c | 220 ++++++++ .../boards/frdm_k32l2b/clock_config.h | 110 ++++ 3 files changed, 821 insertions(+) create mode 100644 hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/clock_config.c create mode 100644 hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.c create mode 100644 hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.h diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/clock_config.c b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/clock_config.c new file mode 100644 index 000000000..2814efc86 --- /dev/null +++ b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/clock_config.c @@ -0,0 +1,491 @@ +/* + * Copyright 2019 ,2021 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ +/* + * How to setup clock using clock driver functions: + * + * 1. Call CLOCK_InitXXX() to configure corresponding SCG clock source. + * Note: The clock could not be set when it is being used as system clock. + * In default out of reset, the CPU is clocked from FIRC(IRC48M), + * so before setting FIRC, change to use another available clock source. + * + * 2. Call CLOCK_SetXtal0Freq() to set XTAL0 frequency based on board settings. + * + * 3. Call CLOCK_SetXxxModeSysClkConfig() to set SCG mode for Xxx run mode. + * Wait until the system clock source is changed to target source. + * + * 4. If power mode change is needed, call SMC_SetPowerModeProtection() to allow + * corresponding power mode and SMC_SetPowerModeXxx() to change to Xxx mode. + * Supported run mode and clock restrictions could be found in Reference Manual. + */ + +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Clocks v7.0 +processor: K32L2A41xxxxA +package_id: K32L2A41VLL1A +mcu_data: ksdk2_0 +processor_version: 9.0.0 + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +#include "fsl_smc.h" +#include "clock_config.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define SCG_CLKOUTCNFG_SIRC 2U /*!< SCG CLKOUT clock select: Slow IRC */ +#define SCG_SOSC_DISABLE 0U /*!< System OSC disabled */ +#define SCG_SPLL_DISABLE 0U /*!< System PLL disabled */ +#define SCG_SYS_OSC_CAP_0P 0U /*!< Oscillator 0pF capacitor load */ + +/******************************************************************************* + * Variables + ******************************************************************************/ +/* System clock frequency. */ +extern uint32_t SystemCoreClock; + +/******************************************************************************* + * Code + ******************************************************************************/ +/*FUNCTION********************************************************************** + * + * Function Name : CLOCK_CONFIG_SetScgOutSel + * Description : Set the SCG clock out select (CLKOUTSEL). + * Param setting : The selected clock source. + * + *END**************************************************************************/ +static void CLOCK_CONFIG_SetScgOutSel(uint8_t setting) +{ + SCG->CLKOUTCNFG = SCG_CLKOUTCNFG_CLKOUTSEL(setting); +} + +/*FUNCTION********************************************************************** + * + * Function Name : CLOCK_CONFIG_FircSafeConfig + * Description : This function is used to safely configure FIRC clock. + * In default out of reset, the CPU is clocked from FIRC(IRC48M). + * Before setting FIRC, change to use SIRC as system clock, + * then configure FIRC. After FIRC is set, change back to use FIRC + * in case SIRC need to be configured. + * Param fircConfig : FIRC configuration. + * + *END**************************************************************************/ +static void CLOCK_CONFIG_FircSafeConfig(const scg_firc_config_t *fircConfig) +{ + scg_sys_clk_config_t curConfig; + const scg_sirc_config_t scgSircConfig = {.enableMode = kSCG_SircEnable, + .div1 = kSCG_AsyncClkDisable, + .div3 = kSCG_AsyncClkDivBy2, + .range = kSCG_SircRangeHigh}; + scg_sys_clk_config_t sysClkSafeConfigSource = { + .divSlow = kSCG_SysClkDivBy4, /* Slow clock divider */ +#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) + .reserved1 = 0, + .reserved2 = 0, + .reserved3 = 0, +#endif + .divCore = kSCG_SysClkDivBy1, /* Core clock divider */ +#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) + .reserved4 = 0, +#endif + .src = kSCG_SysClkSrcSirc, /* System clock source */ +#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) + .reserved5 = 0, +#endif + }; + /* Init Sirc. */ + CLOCK_InitSirc(&scgSircConfig); + /* Change to use SIRC as system clock source to prepare to change FIRCCFG register. */ + CLOCK_SetRunModeSysClkConfig(&sysClkSafeConfigSource); + /* Wait for clock source switch finished. */ + do + { + CLOCK_GetCurSysClkConfig(&curConfig); + } while (curConfig.src != sysClkSafeConfigSource.src); + + /* Init Firc. */ + CLOCK_InitFirc(fircConfig); + /* Change back to use FIRC as system clock source in order to configure SIRC if needed. */ + sysClkSafeConfigSource.src = kSCG_SysClkSrcFirc; + CLOCK_SetRunModeSysClkConfig(&sysClkSafeConfigSource); + /* Wait for clock source switch finished. */ + do + { + CLOCK_GetCurSysClkConfig(&curConfig); + } while (curConfig.src != sysClkSafeConfigSource.src); +} + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ +void BOARD_InitBootClocks(void) +{ + BOARD_BootClockRUN(); +} + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockRUN +called_from_default_init: true +outputs: +- {id: Core_clock.outFreq, value: 48 MHz} +- {id: FIRCDIV1_CLK.outFreq, value: 48 MHz} +- {id: FIRCDIV3_CLK.outFreq, value: 48 MHz} +- {id: LPO_clock.outFreq, value: 1 kHz} +- {id: OSC32KCLK.outFreq, value: 32.768 kHz} +- {id: SIRCDIV3_CLK.outFreq, value: 4 MHz} +- {id: SIRC_CLK.outFreq, value: 8 MHz} +- {id: SOSCDIV3_CLK.outFreq, value: 32.768 kHz} +- {id: SOSCER_CLK.outFreq, value: 32.768 kHz} +- {id: SOSC_CLK.outFreq, value: 32.768 kHz} +- {id: Slow_clock.outFreq, value: 24 MHz} +- {id: System_clock.outFreq, value: 48 MHz} +settings: +- {id: SCG.FIRCDIV1.scale, value: '1', locked: true} +- {id: SCG.FIRCDIV3.scale, value: '1', locked: true} +- {id: SCG.SIRCDIV3.scale, value: '2', locked: true} +- {id: SCG.SOSCDIV3.scale, value: '1', locked: true} +- {id: SCG_SOSCCFG_OSC_MODE_CFG, value: ModeOscLowPower} +- {id: SCG_SOSCCSR_SOSCEN_CFG, value: Enabled} +- {id: SCG_SOSCCSR_SOSCERCLKEN_CFG, value: Enabled} +sources: +- {id: SCG.SOSC.outFreq, value: 32.768 kHz, enabled: true} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockRUN configuration + ******************************************************************************/ +const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockRUN = + { + .divSlow = kSCG_SysClkDivBy2, /* Slow Clock Divider: divided by 2 */ +#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) + .reserved1 = 0, + .reserved2 = 0, + .reserved3 = 0, +#endif + .divCore = kSCG_SysClkDivBy1, /* Core Clock Divider: divided by 1 */ +#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) + .reserved4 = 0, +#endif + .src = kSCG_SysClkSrcFirc, /* Fast IRC is selected as System Clock Source */ +#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) + .reserved5 = 0, +#endif + }; +const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockRUN = + { + .freq = 32768U, /* System Oscillator frequency: 32768Hz */ + .enableMode = kSCG_SysOscEnable | kSCG_SysOscEnableErClk,/* Enable System OSC clock, Enable OSCERCLK */ + .monitorMode = kSCG_SysOscMonitorDisable, /* Monitor disabled */ + .div1 = kSCG_AsyncClkDisable, /* System OSC Clock Divider 1: Clock output is disabled */ + .div3 = kSCG_AsyncClkDivBy1, /* System OSC Clock Divider 3: divided by 1 */ + .capLoad = SCG_SYS_OSC_CAP_0P, /* Oscillator capacity load: 0pF */ + .workMode = kSCG_SysOscModeOscLowPower, /* Oscillator low power */ + }; +const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockRUN = + { + .enableMode = kSCG_SircEnable | kSCG_SircEnableInLowPower,/* Enable SIRC clock, Enable SIRC in low power mode */ + .div1 = kSCG_AsyncClkDisable, /* Slow IRC Clock Divider 1: Clock output is disabled */ + .div3 = kSCG_AsyncClkDivBy2, /* Slow IRC Clock Divider 3: divided by 2 */ + .range = kSCG_SircRangeHigh, /* Slow IRC high range clock (8 MHz) */ + }; +const scg_firc_config_t g_scgFircConfig_BOARD_BootClockRUN = + { + .enableMode = kSCG_FircEnable, /* Enable FIRC clock */ + .div1 = kSCG_AsyncClkDivBy1, /* Fast IRC Clock Divider 1: divided by 1 */ + .div3 = kSCG_AsyncClkDivBy1, /* Fast IRC Clock Divider 3: divided by 1 */ + .range = kSCG_FircRange48M, /* Fast IRC is trimmed to 48MHz */ + .trimConfig = NULL, /* Fast IRC Trim disabled */ + }; +const scg_spll_config_t g_scgSysPllConfig_BOARD_BootClockRUN = + { + .enableMode = SCG_SPLL_DISABLE, /* System PLL disabled */ + .monitorMode = kSCG_SysPllMonitorDisable, /* Monitor disabled */ + .div1 = kSCG_AsyncClkDisable, /* System PLL Clock Divider 1: Clock output is disabled */ + .div3 = kSCG_AsyncClkDisable, /* System PLL Clock Divider 3: Clock output is disabled */ + .src = kSCG_SysPllSrcSysOsc, /* System PLL clock source is System OSC */ + .prediv = 0, /* Divided by 1 */ + .mult = 0, /* Multiply Factor is 16 */ + }; +/******************************************************************************* + * Code for BOARD_BootClockRUN configuration + ******************************************************************************/ +void BOARD_BootClockRUN(void) +{ + scg_sys_clk_config_t curConfig; + + /* Init SOSC according to board configuration. */ + CLOCK_InitSysOsc(&g_scgSysOscConfig_BOARD_BootClockRUN); + /* Set the XTAL0 frequency based on board settings. */ + CLOCK_SetXtal0Freq(g_scgSysOscConfig_BOARD_BootClockRUN.freq); + /* Init FIRC. */ + CLOCK_CONFIG_FircSafeConfig(&g_scgFircConfig_BOARD_BootClockRUN); + /* Init SIRC. */ + CLOCK_InitSirc(&g_scgSircConfig_BOARD_BootClockRUN); + /* Set SCG to FIRC mode. */ + CLOCK_SetRunModeSysClkConfig(&g_sysClkConfig_BOARD_BootClockRUN); + /* Wait for clock source switch finished. */ + do + { + CLOCK_GetCurSysClkConfig(&curConfig); + } while (curConfig.src != g_sysClkConfig_BOARD_BootClockRUN.src); + /* Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; +} + +/******************************************************************************* + ********************* Configuration BOARD_BootClockHSRUN ********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockHSRUN +outputs: +- {id: CLKOUT.outFreq, value: 8 MHz} +- {id: Core_clock.outFreq, value: 96 MHz, locked: true, accuracy: '0.001'} +- {id: FIRCDIV1_CLK.outFreq, value: 48 MHz} +- {id: FIRCDIV3_CLK.outFreq, value: 48 MHz} +- {id: LPO_clock.outFreq, value: 1 kHz} +- {id: OSC32KCLK.outFreq, value: 32.768 kHz} +- {id: PLLDIV1_CLK.outFreq, value: 96 MHz} +- {id: PLLDIV3_CLK.outFreq, value: 96 MHz} +- {id: SIRCDIV1_CLK.outFreq, value: 8 MHz} +- {id: SIRCDIV3_CLK.outFreq, value: 8 MHz} +- {id: SIRC_CLK.outFreq, value: 8 MHz} +- {id: SOSCDIV1_CLK.outFreq, value: 32.768 kHz} +- {id: SOSCDIV3_CLK.outFreq, value: 32.768 kHz} +- {id: SOSCER_CLK.outFreq, value: 32.768 kHz} +- {id: SOSC_CLK.outFreq, value: 32.768 kHz} +- {id: Slow_clock.outFreq, value: 24 MHz, locked: true, accuracy: '0.001'} +- {id: System_clock.outFreq, value: 96 MHz} +settings: +- {id: SCGMode, value: SPLL} +- {id: powerMode, value: HSRUN} +- {id: CLKOUTConfig, value: 'yes'} +- {id: SCG.DIVSLOW.scale, value: '4'} +- {id: SCG.FIRCDIV1.scale, value: '1', locked: true} +- {id: SCG.FIRCDIV3.scale, value: '1', locked: true} +- {id: SCG.PREDIV.scale, value: '4'} +- {id: SCG.SCSSEL.sel, value: SCG.SPLL_DIV2_CLK} +- {id: SCG.SIRCDIV1.scale, value: '1', locked: true} +- {id: SCG.SIRCDIV3.scale, value: '1', locked: true} +- {id: SCG.SOSCDIV1.scale, value: '1', locked: true} +- {id: SCG.SOSCDIV3.scale, value: '1', locked: true} +- {id: SCG.SPLLDIV1.scale, value: '1', locked: true} +- {id: SCG.SPLLDIV3.scale, value: '1', locked: true} +- {id: SCG.SPLLSRCSEL.sel, value: SCG.FIRC} +- {id: SCG_SOSCCFG_OSC_MODE_CFG, value: ModeOscLowPower} +- {id: SCG_SOSCCSR_SOSCEN_CFG, value: Enabled} +- {id: SCG_SOSCCSR_SOSCERCLKEN_CFG, value: Enabled} +- {id: SCG_SPLLCSR_SPLLEN_CFG, value: Enabled} +sources: +- {id: SCG.SOSC.outFreq, value: 32.768 kHz, enabled: true} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockHSRUN configuration + ******************************************************************************/ +const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockHSRUN = + { + .divSlow = kSCG_SysClkDivBy4, /* Slow Clock Divider: divided by 4 */ +#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) + .reserved1 = 0, + .reserved2 = 0, + .reserved3 = 0, +#endif + .divCore = kSCG_SysClkDivBy1, /* Core Clock Divider: divided by 1 */ +#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) + .reserved4 = 0, +#endif + .src = kSCG_SysClkSrcSysPll, /* System PLL is selected as System Clock Source */ +#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) + .reserved5 = 0, +#endif + }; +const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockHSRUN = + { + .freq = 32768U, /* System Oscillator frequency: 32768Hz */ + .enableMode = kSCG_SysOscEnable | kSCG_SysOscEnableErClk,/* Enable System OSC clock, Enable OSCERCLK */ + .monitorMode = kSCG_SysOscMonitorDisable, /* Monitor disabled */ + .div1 = kSCG_AsyncClkDivBy1, /* System OSC Clock Divider 1: divided by 1 */ + .div3 = kSCG_AsyncClkDivBy1, /* System OSC Clock Divider 3: divided by 1 */ + .capLoad = SCG_SYS_OSC_CAP_0P, /* Oscillator capacity load: 0pF */ + .workMode = kSCG_SysOscModeOscLowPower, /* Oscillator low power */ + }; +const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockHSRUN = + { + .enableMode = kSCG_SircEnable | kSCG_SircEnableInLowPower,/* Enable SIRC clock, Enable SIRC in low power mode */ + .div1 = kSCG_AsyncClkDivBy1, /* Slow IRC Clock Divider 1: divided by 1 */ + .div3 = kSCG_AsyncClkDivBy1, /* Slow IRC Clock Divider 3: divided by 1 */ + .range = kSCG_SircRangeHigh, /* Slow IRC high range clock (8 MHz) */ + }; +const scg_firc_config_t g_scgFircConfig_BOARD_BootClockHSRUN = + { + .enableMode = kSCG_FircEnable, /* Enable FIRC clock */ + .div1 = kSCG_AsyncClkDivBy1, /* Fast IRC Clock Divider 1: divided by 1 */ + .div3 = kSCG_AsyncClkDivBy1, /* Fast IRC Clock Divider 3: divided by 1 */ + .range = kSCG_FircRange48M, /* Fast IRC is trimmed to 48MHz */ + .trimConfig = NULL, /* Fast IRC Trim disabled */ + }; +const scg_spll_config_t g_scgSysPllConfig_BOARD_BootClockHSRUN = + { + .enableMode = kSCG_SysPllEnable, /* Enable SPLL clock */ + .monitorMode = kSCG_SysPllMonitorDisable, /* Monitor disabled */ + .div1 = kSCG_AsyncClkDivBy1, /* System PLL Clock Divider 1: divided by 1 */ + .div3 = kSCG_AsyncClkDivBy1, /* System PLL Clock Divider 3: divided by 1 */ + .src = kSCG_SysPllSrcFirc, /* System PLL clock source is Fast IRC */ + .prediv = 3, /* Divided by 4 */ + .mult = 0, /* Multiply Factor is 16 */ + }; +/******************************************************************************* + * Code for BOARD_BootClockHSRUN configuration + ******************************************************************************/ +void BOARD_BootClockHSRUN(void) +{ + scg_sys_clk_config_t curConfig; + + /* Init SOSC according to board configuration. */ + CLOCK_InitSysOsc(&g_scgSysOscConfig_BOARD_BootClockHSRUN); + /* Set the XTAL0 frequency based on board settings. */ + CLOCK_SetXtal0Freq(g_scgSysOscConfig_BOARD_BootClockHSRUN.freq); + /* Init FIRC. */ + CLOCK_CONFIG_FircSafeConfig(&g_scgFircConfig_BOARD_BootClockHSRUN); + /* Init SIRC. */ + CLOCK_InitSirc(&g_scgSircConfig_BOARD_BootClockHSRUN); + /* Init SysPll. */ + CLOCK_InitSysPll(&g_scgSysPllConfig_BOARD_BootClockHSRUN); + /* Set HSRUN power mode. */ + SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll); + SMC_SetPowerModeHsrun(SMC); + while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateHsrun) + { + } + + /* Set SCG to SPLL mode. */ + CLOCK_SetHsrunModeSysClkConfig(&g_sysClkConfig_BOARD_BootClockHSRUN); + /* Wait for clock source switch finished. */ + do + { + CLOCK_GetCurSysClkConfig(&curConfig); + } while (curConfig.src != g_sysClkConfig_BOARD_BootClockHSRUN.src); + /* Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKHSRUN_CORE_CLOCK; + /* Set SCG CLKOUT selection. */ + CLOCK_CONFIG_SetScgOutSel(SCG_CLKOUTCNFG_SIRC); +} + +/******************************************************************************* + ********************* Configuration BOARD_BootClockVLPR *********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockVLPR +outputs: +- {id: Core_clock.outFreq, value: 8 MHz, locked: true, accuracy: '0.001'} +- {id: LPO_clock.outFreq, value: 1 kHz} +- {id: SIRC_CLK.outFreq, value: 8 MHz} +- {id: Slow_clock.outFreq, value: 1 MHz, locked: true, accuracy: '0.001'} +- {id: System_clock.outFreq, value: 8 MHz} +settings: +- {id: SCGMode, value: SIRC} +- {id: powerMode, value: VLPR} +- {id: SCG.DIVSLOW.scale, value: '8'} +- {id: SCG.SCSSEL.sel, value: SCG.SIRC} +- {id: SCG_FIRCCSR_FIRCLPEN_CFG, value: Enabled} +sources: +- {id: SCG.SOSC.outFreq, value: 32.768 kHz, enabled: true} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockVLPR configuration + ******************************************************************************/ +const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockVLPR = + { + .divSlow = kSCG_SysClkDivBy8, /* Slow Clock Divider: divided by 8 */ +#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) + .reserved1 = 0, + .reserved2 = 0, + .reserved3 = 0, +#endif + .divCore = kSCG_SysClkDivBy1, /* Core Clock Divider: divided by 1 */ +#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) + .reserved4 = 0, +#endif + .src = kSCG_SysClkSrcSirc, /* Slow IRC is selected as System Clock Source */ +#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) + .reserved5 = 0, +#endif + }; +const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockVLPR = + { + .freq = 0U, /* System Oscillator frequency: 0Hz */ + .enableMode = SCG_SOSC_DISABLE, /* System OSC disabled */ + .monitorMode = kSCG_SysOscMonitorDisable, /* Monitor disabled */ + .div1 = kSCG_AsyncClkDisable, /* System OSC Clock Divider 1: Clock output is disabled */ + .div3 = kSCG_AsyncClkDisable, /* System OSC Clock Divider 3: Clock output is disabled */ + .capLoad = SCG_SYS_OSC_CAP_0P, /* Oscillator capacity load: 0pF */ + .workMode = kSCG_SysOscModeExt, /* Use external clock */ + }; +const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockVLPR = + { + .enableMode = kSCG_SircEnable | kSCG_SircEnableInLowPower,/* Enable SIRC clock, Enable SIRC in low power mode */ + .div1 = kSCG_AsyncClkDisable, /* Slow IRC Clock Divider 1: Clock output is disabled */ + .div3 = kSCG_AsyncClkDisable, /* Slow IRC Clock Divider 3: Clock output is disabled */ + .range = kSCG_SircRangeHigh, /* Slow IRC high range clock (8 MHz) */ + }; +const scg_firc_config_t g_scgFircConfig_BOARD_BootClockVLPR = + { + .enableMode = kSCG_FircEnable | kSCG_FircEnableInLowPower,/* Enable FIRC clock, Enable FIRC in low power mode */ + .div1 = kSCG_AsyncClkDisable, /* Fast IRC Clock Divider 1: Clock output is disabled */ + .div3 = kSCG_AsyncClkDisable, /* Fast IRC Clock Divider 3: Clock output is disabled */ + .range = kSCG_FircRange48M, /* Fast IRC is trimmed to 48MHz */ + .trimConfig = NULL, /* Fast IRC Trim disabled */ + }; +const scg_spll_config_t g_scgSysPllConfig_BOARD_BootClockVLPR = + { + .enableMode = SCG_SPLL_DISABLE, /* System PLL disabled */ + .monitorMode = kSCG_SysPllMonitorDisable, /* Monitor disabled */ + .div1 = kSCG_AsyncClkDisable, /* System PLL Clock Divider 1: Clock output is disabled */ + .div3 = kSCG_AsyncClkDisable, /* System PLL Clock Divider 3: Clock output is disabled */ + .src = kSCG_SysPllSrcSysOsc, /* System PLL clock source is System OSC */ + .prediv = 0, /* Divided by 1 */ + .mult = 0, /* Multiply Factor is 16 */ + }; +/******************************************************************************* + * Code for BOARD_BootClockVLPR configuration + ******************************************************************************/ +void BOARD_BootClockVLPR(void) +{ + /* Init FIRC. */ + CLOCK_CONFIG_FircSafeConfig(&g_scgFircConfig_BOARD_BootClockVLPR); + /* Init SIRC. */ + CLOCK_InitSirc(&g_scgSircConfig_BOARD_BootClockVLPR); + /* Allow SMC all power modes. */ + SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll); + /* Set VLPR power mode. */ + SMC_SetPowerModeVlpr(SMC); + while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateVlpr) + { + } + /* Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKVLPR_CORE_CLOCK; +} diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.c b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.c new file mode 100644 index 000000000..e74000827 --- /dev/null +++ b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.c @@ -0,0 +1,220 @@ +/* + * Copyright 2019 ,2021 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ +/* + * How to setup clock using clock driver functions: + * + * 1. CLOCK_SetSimSafeDivs, to make sure core clock, bus clock, flexbus clock + * and flash clock are in allowed range during clock mode switch. + * + * 2. Call CLOCK_Osc0Init to setup OSC clock, if it is used in target mode. + * + * 3. Call CLOCK_SetMcgliteConfig to set MCG_Lite configuration. + * + * 4. Call CLOCK_SetSimConfig to set the clock configuration in SIM. + */ + +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Clocks v7.0 +processor: K32L2B31xxxxA +package_id: K32L2B31VLH0A +mcu_data: ksdk2_0 +processor_version: 9.0.0 +board: FRDM-K32L2B + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +#include "fsl_smc.h" +#include "clock_config.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define OSC_CAP0P 0U /*!< Oscillator 0pF capacitor load */ +#define OSC_ER_CLK_DISABLE 0U /*!< Disable external reference clock */ +#define SIM_OSC32KSEL_OSC32KCLK_CLK 0U /*!< OSC32KSEL select: OSC32KCLK clock */ + +/******************************************************************************* + * Variables + ******************************************************************************/ +/* System clock frequency. */ +extern uint32_t SystemCoreClock; + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ +void BOARD_InitBootClocks(void) +{ + BOARD_BootClockRUN(); +} + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockRUN +called_from_default_init: true +outputs: +- {id: Bus_clock.outFreq, value: 24 MHz} +- {id: Core_clock.outFreq, value: 48 MHz} +- {id: Flash_clock.outFreq, value: 24 MHz} +- {id: LPO_clock.outFreq, value: 1 kHz} +- {id: MCGIRCLK.outFreq, value: 8 MHz} +- {id: MCGPCLK.outFreq, value: 48 MHz} +- {id: System_clock.outFreq, value: 48 MHz} +settings: +- {id: MCGMode, value: HIRC} +- {id: MCG.CLKS.sel, value: MCG.HIRC} +- {id: MCG_C2_OSC_MODE_CFG, value: ModeOscLowPower} +- {id: MCG_C2_RANGE0_CFG, value: Very_high} +- {id: MCG_MC_HIRCEN_CFG, value: Enabled} +- {id: OSC0_CR_ERCLKEN_CFG, value: Enabled} +- {id: OSC_CR_ERCLKEN_CFG, value: Enabled} +- {id: SIM.CLKOUTSEL.sel, value: MCG.MCGPCLK} +- {id: SIM.COPCLKSEL.sel, value: OSC.OSCERCLK} +- {id: SIM.FLEXIOSRCSEL.sel, value: MCG.MCGPCLK} +- {id: SIM.LPUART0SRCSEL.sel, value: MCG.MCGPCLK} +- {id: SIM.LPUART1SRCSEL.sel, value: MCG.MCGPCLK} +- {id: SIM.RTCCLKOUTSEL.sel, value: OSC.OSCERCLK} +- {id: SIM.TPMSRCSEL.sel, value: MCG.MCGPCLK} +- {id: SIM.USBSRCSEL.sel, value: MCG.MCGPCLK} +sources: +- {id: MCG.HIRC.outFreq, value: 48 MHz} +- {id: OSC.OSC.outFreq, value: 32 MHz} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * 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_OSC32KCLK_CLK, /* OSC32KSEL select: OSC32KCLK clock */ + .clkdiv1 = 0x10000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV4: /2 */ + }; +const osc_config_t oscConfig_BOARD_BootClockRUN = + { + .freq = 0U, /* Oscillator frequency: 0Hz */ + .capLoad = (OSC_CAP0P), /* Oscillator capacity load: 0pF */ + .workMode = kOSC_ModeOscLowPower, /* Oscillator low power */ + .oscerConfig = + { + .enableMode = kOSC_ErClkEnable, /* Enable external reference clock, disable external reference clock in STOP mode */ + } + }; + +/******************************************************************************* + * 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; +} + +/******************************************************************************* + ********************* Configuration BOARD_BootClockVLPR *********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockVLPR +outputs: +- {id: Bus_clock.outFreq, value: 1 MHz} +- {id: Core_clock.outFreq, value: 2 MHz} +- {id: Flash_clock.outFreq, value: 1 MHz} +- {id: LPO_clock.outFreq, value: 1 kHz} +- {id: MCGIRCLK.outFreq, value: 2 MHz} +- {id: System_clock.outFreq, value: 2 MHz} +settings: +- {id: MCGMode, value: LIRC2M} +- {id: powerMode, value: VLPR} +- {id: MCG_C2_OSC_MODE_CFG, value: ModeOscLowPower} +- {id: RTCCLKOUTConfig, value: 'yes'} +- {id: SIM.OUTDIV4.scale, value: '2', locked: true} +- {id: SIM.RTCCLKOUTSEL.sel, value: OSC.OSCERCLK} +sources: +- {id: MCG.LIRC.outFreq, value: 2 MHz} +- {id: OSC.OSC.outFreq, value: 32.768 kHz} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockVLPR configuration + ******************************************************************************/ +const mcglite_config_t mcgliteConfig_BOARD_BootClockVLPR = + { + .outSrc = kMCGLITE_ClkSrcLirc, /* MCGOUTCLK source is LIRC */ + .irclkEnableMode = kMCGLITE_IrclkEnable, /* MCGIRCLK enabled, MCGIRCLK disabled in STOP mode */ + .ircs = kMCGLITE_Lirc2M, /* Slow internal reference (LIRC) 2 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 = false, /* HIRC source is not enabled */ + }; +const sim_clock_config_t simConfig_BOARD_BootClockVLPR = + { + .er32kSrc = SIM_OSC32KSEL_OSC32KCLK_CLK, /* OSC32KSEL select: OSC32KCLK clock */ + .clkdiv1 = 0x10000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV4: /2 */ + }; +const osc_config_t oscConfig_BOARD_BootClockVLPR = + { + .freq = 0U, /* Oscillator frequency: 0Hz */ + .capLoad = (OSC_CAP0P), /* Oscillator capacity load: 0pF */ + .workMode = kOSC_ModeOscLowPower, /* Oscillator low power */ + .oscerConfig = + { + .enableMode = OSC_ER_CLK_DISABLE, /* Disable external reference clock */ + } + }; + +/******************************************************************************* + * Code for BOARD_BootClockVLPR configuration + ******************************************************************************/ +void BOARD_BootClockVLPR(void) +{ + /* Set the system clock dividers in SIM to safe value. */ + CLOCK_SetSimSafeDivs(); + /* Set MCG to LIRC2M mode. */ + CLOCK_SetMcgliteConfig(&mcgliteConfig_BOARD_BootClockVLPR); + /* Set the clock configuration in SIM module. */ + CLOCK_SetSimConfig(&simConfig_BOARD_BootClockVLPR); + /* Set VLPR power mode. */ + SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll); +#if (defined(FSL_FEATURE_SMC_HAS_LPWUI) && FSL_FEATURE_SMC_HAS_LPWUI) + SMC_SetPowerModeVlpr(SMC, false); +#else + SMC_SetPowerModeVlpr(SMC); +#endif + while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateVlpr) + { + } + /* Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKVLPR_CORE_CLOCK; +} diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.h b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.h new file mode 100644 index 000000000..37328e7d8 --- /dev/null +++ b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.h @@ -0,0 +1,110 @@ +/* + * Copyright 2019 ,2021 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _CLOCK_CONFIG_H_ +#define _CLOCK_CONFIG_H_ + +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes default configuration of clocks. + * + */ +void BOARD_InitBootClocks(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockRUN configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */ + +/*! @brief MCG lite set for BOARD_BootClockRUN configuration. + */ +extern const mcglite_config_t mcgliteConfig_BOARD_BootClockRUN; +/*! @brief SIM module set for BOARD_BootClockRUN configuration. + */ +extern const sim_clock_config_t simConfig_BOARD_BootClockRUN; +/*! @brief OSC set for BOARD_BootClockRUN configuration. + */ +extern const osc_config_t oscConfig_BOARD_BootClockRUN; + +/******************************************************************************* + * API for BOARD_BootClockRUN configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockRUN(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ********************* Configuration BOARD_BootClockVLPR *********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockVLPR configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKVLPR_CORE_CLOCK 2000000U /*!< Core clock frequency: 2000000Hz */ + +/*! @brief MCG lite set for BOARD_BootClockVLPR configuration. + */ +extern const mcglite_config_t mcgliteConfig_BOARD_BootClockVLPR; +/*! @brief SIM module set for BOARD_BootClockVLPR configuration. + */ +extern const sim_clock_config_t simConfig_BOARD_BootClockVLPR; +/*! @brief OSC set for BOARD_BootClockVLPR configuration. + */ +extern const osc_config_t oscConfig_BOARD_BootClockVLPR; + +/******************************************************************************* + * API for BOARD_BootClockVLPR configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockVLPR(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +#endif /* _CLOCK_CONFIG_H_ */ From 5ce458588498090204cdc7c3977c0fd48e00d710 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 5 Apr 2024 17:14:51 +0700 Subject: [PATCH 236/454] fix pre-commit format --- examples/build_system/make/cpu/cortex-m33-nodsp-nofp.mk | 2 +- hw/bsp/mcx/boards/frdmmcxa153/board.mk | 2 +- hw/bsp/mcx/boards/frdmmcxa153/clock_config.h | 2 +- hw/bsp/mcx/boards/frdmmcxa153/pin_mux.c | 2 +- hw/bsp/mcx/family.c | 2 +- hw/bsp/mcx/family.cmake | 6 +++--- hw/bsp/mcx/family.mk | 4 ++-- src/portable/chipidea/ci_fs/ci_fs_mcx.h | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/examples/build_system/make/cpu/cortex-m33-nodsp-nofp.mk b/examples/build_system/make/cpu/cortex-m33-nodsp-nofp.mk index f74f46d54..c65f24376 100644 --- a/examples/build_system/make/cpu/cortex-m33-nodsp-nofp.mk +++ b/examples/build_system/make/cpu/cortex-m33-nodsp-nofp.mk @@ -13,4 +13,4 @@ else ifeq ($(TOOLCHAIN),iar) endif -FREERTOS_PORTABLE_SRC ?= $(FREERTOS_PORTABLE_PATH)/ARM_CM33_NTZ/non_secure \ No newline at end of file +FREERTOS_PORTABLE_SRC ?= $(FREERTOS_PORTABLE_PATH)/ARM_CM33_NTZ/non_secure diff --git a/hw/bsp/mcx/boards/frdmmcxa153/board.mk b/hw/bsp/mcx/boards/frdmmcxa153/board.mk index a70a7dcef..cf6d9c0eb 100644 --- a/hw/bsp/mcx/boards/frdmmcxa153/board.mk +++ b/hw/bsp/mcx/boards/frdmmcxa153/board.mk @@ -6,7 +6,7 @@ CPU_CORE ?= cortex-m33-nodsp-nofp CFLAGS += \ -DCPU_MCXA153VLH \ -DCFG_TUSB_MCU=OPT_MCU_MCXA15 \ - + JLINK_DEVICE = MCXA153 PYOCD_TARGET = MCXA153 diff --git a/hw/bsp/mcx/boards/frdmmcxa153/clock_config.h b/hw/bsp/mcx/boards/frdmmcxa153/clock_config.h index 079d0d312..aae811052 100644 --- a/hw/bsp/mcx/boards/frdmmcxa153/clock_config.h +++ b/hw/bsp/mcx/boards/frdmmcxa153/clock_config.h @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: BSD-3-Clause */ - + /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. diff --git a/hw/bsp/mcx/boards/frdmmcxa153/pin_mux.c b/hw/bsp/mcx/boards/frdmmcxa153/pin_mux.c index b0e6de560..cc8f56e63 100644 --- a/hw/bsp/mcx/boards/frdmmcxa153/pin_mux.c +++ b/hw/bsp/mcx/boards/frdmmcxa153/pin_mux.c @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: BSD-3-Clause */ - + /*********************************************************************************************************************** * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. diff --git a/hw/bsp/mcx/family.c b/hw/bsp/mcx/family.c index 74b84773d..96ae2fde3 100644 --- a/hw/bsp/mcx/family.c +++ b/hw/bsp/mcx/family.c @@ -151,7 +151,7 @@ void board_init(void) CLOCK_EnableClock(kCLOCK_Usb0Ram); CLOCK_EnableClock(kCLOCK_Usb0Fs); CLOCK_EnableUsbfsClock(); - + #endif #if PORT_SUPPORT_DEVICE(1) && (CFG_TUSB_MCU == OPT_MCU_MCXN9) diff --git a/hw/bsp/mcx/family.cmake b/hw/bsp/mcx/family.cmake index 078d13b9f..78490ec57 100644 --- a/hw/bsp/mcx/family.cmake +++ b/hw/bsp/mcx/family.cmake @@ -27,13 +27,13 @@ function(add_board_target BOARD_TARGET) ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_gpio.c ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_common_arm.c ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_lpuart.c - + # mcu ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_reset.c ${SDK_DIR}/devices/${MCU_VARIANT}/system_${MCU_CORE}.c ) - + if (${FAMILY_MCUS} STREQUAL "MCXN9") target_sources(${BOARD_TARGET} PRIVATE ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_lpflexcomm.c @@ -105,7 +105,7 @@ function(family_configure_example TARGET RTOS) elseif(${FAMILY_MCUS} STREQUAL "MCXA15") family_add_tinyusb(${TARGET} OPT_MCU_MCXA15 ${RTOS}) endif() - + target_sources(${TARGET}-tinyusb PUBLIC # TinyUSB: Port0 is chipidea FS, Port1 is chipidea HS ${TOP}/src/portable/chipidea/$ diff --git a/hw/bsp/mcx/family.mk b/hw/bsp/mcx/family.mk index 59170271c..3ee0efaf6 100644 --- a/hw/bsp/mcx/family.mk +++ b/hw/bsp/mcx/family.mk @@ -38,7 +38,7 @@ SRC_C += \ $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_gpio.c \ $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_lpuart.c \ $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_common_arm.c \ - + # fsl_lpflexcomm just needed for MCXN9 ifeq ($(MCU_VARIANT), MCXN947) @@ -54,7 +54,7 @@ ifeq ($(MCU_VARIANT), MCXA153) endif - + INC += \ $(TOP)/$(BOARD_PATH) \ diff --git a/src/portable/chipidea/ci_fs/ci_fs_mcx.h b/src/portable/chipidea/ci_fs/ci_fs_mcx.h index bf88df0f4..3f2b13323 100644 --- a/src/portable/chipidea/ci_fs/ci_fs_mcx.h +++ b/src/portable/chipidea/ci_fs/ci_fs_mcx.h @@ -36,7 +36,7 @@ #elif CFG_TUSB_MCU == OPT_MCU_MCXA15 #define CI_FS_REG(_port) ((ci_fs_regs_t*) USB0_BASE) #define USB0_IRQN USB0_IRQn - + #else #error "MCU is not supported" #endif From 4b59f8010079fad302bf0c4b8f2a63b2c776b29a Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 5 Apr 2024 18:09:29 +0700 Subject: [PATCH 237/454] more reverted: re-add clock_config.h --- .../boards/frdm_k32l2a4s/clock_config.h | 164 ++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/clock_config.h diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/clock_config.h b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/clock_config.h new file mode 100644 index 000000000..c01d5e03c --- /dev/null +++ b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/clock_config.h @@ -0,0 +1,164 @@ +/* + * Copyright 2019 ,2021 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _CLOCK_CONFIG_H_ +#define _CLOCK_CONFIG_H_ + +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define BOARD_XTAL0_CLK_HZ 32768U /*!< Board xtal0 frequency in Hz */ + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes default configuration of clocks. + * + */ +void BOARD_InitBootClocks(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockRUN configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */ + +/*! @brief SCG set for BOARD_BootClockRUN configuration. + */ +extern const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockRUN; +/*! @brief System OSC set for BOARD_BootClockRUN configuration. + */ +extern const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockRUN; +/*! @brief SIRC set for BOARD_BootClockRUN configuration. + */ +extern const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockRUN; +/*! @brief FIRC set for BOARD_BootClockRUN configuration. + */ +extern const scg_firc_config_t g_scgFircConfigBOARD_BootClockRUN; +extern const scg_spll_config_t g_scgSysPllConfigBOARD_BootClockRUN; +/*! @brief Low Power FLL set for BOARD_BootClockRUN configuration. + */ + +/******************************************************************************* + * API for BOARD_BootClockRUN configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockRUN(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ********************* Configuration BOARD_BootClockHSRUN ********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockHSRUN configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKHSRUN_CORE_CLOCK 96000000U /*!< Core clock frequency: 96000000Hz */ + +/*! @brief SCG set for BOARD_BootClockHSRUN configuration. + */ +extern const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockHSRUN; +/*! @brief System OSC set for BOARD_BootClockHSRUN configuration. + */ +extern const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockHSRUN; +/*! @brief SIRC set for BOARD_BootClockHSRUN configuration. + */ +extern const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockHSRUN; +/*! @brief FIRC set for BOARD_BootClockHSRUN configuration. + */ +extern const scg_firc_config_t g_scgFircConfigBOARD_BootClockHSRUN; +extern const scg_spll_config_t g_scgSysPllConfigBOARD_BootClockHSRUN; +/*! @brief Low Power FLL set for BOARD_BootClockHSRUN configuration. + */ + +/******************************************************************************* + * API for BOARD_BootClockHSRUN configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockHSRUN(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ********************* Configuration BOARD_BootClockVLPR *********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockVLPR configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKVLPR_CORE_CLOCK 8000000U /*!< Core clock frequency: 8000000Hz */ + +/*! @brief SCG set for BOARD_BootClockVLPR configuration. + */ +extern const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockVLPR; +/*! @brief System OSC set for BOARD_BootClockVLPR configuration. + */ +extern const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockVLPR; +/*! @brief SIRC set for BOARD_BootClockVLPR configuration. + */ +extern const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockVLPR; +/*! @brief FIRC set for BOARD_BootClockVLPR configuration. + */ +extern const scg_firc_config_t g_scgFircConfigBOARD_BootClockVLPR; +extern const scg_spll_config_t g_scgSysPllConfigBOARD_BootClockVLPR; +/*! @brief Low Power FLL set for BOARD_BootClockVLPR configuration. + */ + +/******************************************************************************* + * API for BOARD_BootClockVLPR configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockVLPR(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +#endif /* _CLOCK_CONFIG_H_ */ From 757a1726e8c6eb52f959e5f42a7ae22f769c19c3 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 5 Apr 2024 18:33:58 +0700 Subject: [PATCH 238/454] rename frdm board --- hw/bsp/mcx/boards/{frdmmcxa153 => frdm_mcxa153}/board.cmake | 0 hw/bsp/mcx/boards/{frdmmcxa153 => frdm_mcxa153}/board.h | 0 hw/bsp/mcx/boards/{frdmmcxa153 => frdm_mcxa153}/board.mk | 0 hw/bsp/mcx/boards/{frdmmcxa153 => frdm_mcxa153}/clock_config.c | 0 hw/bsp/mcx/boards/{frdmmcxa153 => frdm_mcxa153}/clock_config.h | 0 hw/bsp/mcx/boards/{frdmmcxa153 => frdm_mcxa153}/pin_mux.c | 0 hw/bsp/mcx/boards/{frdmmcxa153 => frdm_mcxa153}/pin_mux.h | 0 hw/bsp/mcx/boards/{frdmmcxn947 => frdm_mcxn947}/board.cmake | 0 hw/bsp/mcx/boards/{frdmmcxn947 => frdm_mcxn947}/board.h | 0 hw/bsp/mcx/boards/{frdmmcxn947 => frdm_mcxn947}/board.mk | 0 hw/bsp/mcx/boards/{frdmmcxn947 => frdm_mcxn947}/clock_config.c | 0 hw/bsp/mcx/boards/{frdmmcxn947 => frdm_mcxn947}/clock_config.h | 0 hw/bsp/mcx/boards/{frdmmcxn947 => frdm_mcxn947}/pin_mux.c | 0 hw/bsp/mcx/boards/{frdmmcxn947 => frdm_mcxn947}/pin_mux.h | 0 14 files changed, 0 insertions(+), 0 deletions(-) rename hw/bsp/mcx/boards/{frdmmcxa153 => frdm_mcxa153}/board.cmake (100%) rename hw/bsp/mcx/boards/{frdmmcxa153 => frdm_mcxa153}/board.h (100%) rename hw/bsp/mcx/boards/{frdmmcxa153 => frdm_mcxa153}/board.mk (100%) rename hw/bsp/mcx/boards/{frdmmcxa153 => frdm_mcxa153}/clock_config.c (100%) rename hw/bsp/mcx/boards/{frdmmcxa153 => frdm_mcxa153}/clock_config.h (100%) rename hw/bsp/mcx/boards/{frdmmcxa153 => frdm_mcxa153}/pin_mux.c (100%) rename hw/bsp/mcx/boards/{frdmmcxa153 => frdm_mcxa153}/pin_mux.h (100%) rename hw/bsp/mcx/boards/{frdmmcxn947 => frdm_mcxn947}/board.cmake (100%) rename hw/bsp/mcx/boards/{frdmmcxn947 => frdm_mcxn947}/board.h (100%) rename hw/bsp/mcx/boards/{frdmmcxn947 => frdm_mcxn947}/board.mk (100%) rename hw/bsp/mcx/boards/{frdmmcxn947 => frdm_mcxn947}/clock_config.c (100%) rename hw/bsp/mcx/boards/{frdmmcxn947 => frdm_mcxn947}/clock_config.h (100%) rename hw/bsp/mcx/boards/{frdmmcxn947 => frdm_mcxn947}/pin_mux.c (100%) rename hw/bsp/mcx/boards/{frdmmcxn947 => frdm_mcxn947}/pin_mux.h (100%) diff --git a/hw/bsp/mcx/boards/frdmmcxa153/board.cmake b/hw/bsp/mcx/boards/frdm_mcxa153/board.cmake similarity index 100% rename from hw/bsp/mcx/boards/frdmmcxa153/board.cmake rename to hw/bsp/mcx/boards/frdm_mcxa153/board.cmake diff --git a/hw/bsp/mcx/boards/frdmmcxa153/board.h b/hw/bsp/mcx/boards/frdm_mcxa153/board.h similarity index 100% rename from hw/bsp/mcx/boards/frdmmcxa153/board.h rename to hw/bsp/mcx/boards/frdm_mcxa153/board.h diff --git a/hw/bsp/mcx/boards/frdmmcxa153/board.mk b/hw/bsp/mcx/boards/frdm_mcxa153/board.mk similarity index 100% rename from hw/bsp/mcx/boards/frdmmcxa153/board.mk rename to hw/bsp/mcx/boards/frdm_mcxa153/board.mk diff --git a/hw/bsp/mcx/boards/frdmmcxa153/clock_config.c b/hw/bsp/mcx/boards/frdm_mcxa153/clock_config.c similarity index 100% rename from hw/bsp/mcx/boards/frdmmcxa153/clock_config.c rename to hw/bsp/mcx/boards/frdm_mcxa153/clock_config.c diff --git a/hw/bsp/mcx/boards/frdmmcxa153/clock_config.h b/hw/bsp/mcx/boards/frdm_mcxa153/clock_config.h similarity index 100% rename from hw/bsp/mcx/boards/frdmmcxa153/clock_config.h rename to hw/bsp/mcx/boards/frdm_mcxa153/clock_config.h diff --git a/hw/bsp/mcx/boards/frdmmcxa153/pin_mux.c b/hw/bsp/mcx/boards/frdm_mcxa153/pin_mux.c similarity index 100% rename from hw/bsp/mcx/boards/frdmmcxa153/pin_mux.c rename to hw/bsp/mcx/boards/frdm_mcxa153/pin_mux.c diff --git a/hw/bsp/mcx/boards/frdmmcxa153/pin_mux.h b/hw/bsp/mcx/boards/frdm_mcxa153/pin_mux.h similarity index 100% rename from hw/bsp/mcx/boards/frdmmcxa153/pin_mux.h rename to hw/bsp/mcx/boards/frdm_mcxa153/pin_mux.h diff --git a/hw/bsp/mcx/boards/frdmmcxn947/board.cmake b/hw/bsp/mcx/boards/frdm_mcxn947/board.cmake similarity index 100% rename from hw/bsp/mcx/boards/frdmmcxn947/board.cmake rename to hw/bsp/mcx/boards/frdm_mcxn947/board.cmake diff --git a/hw/bsp/mcx/boards/frdmmcxn947/board.h b/hw/bsp/mcx/boards/frdm_mcxn947/board.h similarity index 100% rename from hw/bsp/mcx/boards/frdmmcxn947/board.h rename to hw/bsp/mcx/boards/frdm_mcxn947/board.h diff --git a/hw/bsp/mcx/boards/frdmmcxn947/board.mk b/hw/bsp/mcx/boards/frdm_mcxn947/board.mk similarity index 100% rename from hw/bsp/mcx/boards/frdmmcxn947/board.mk rename to hw/bsp/mcx/boards/frdm_mcxn947/board.mk diff --git a/hw/bsp/mcx/boards/frdmmcxn947/clock_config.c b/hw/bsp/mcx/boards/frdm_mcxn947/clock_config.c similarity index 100% rename from hw/bsp/mcx/boards/frdmmcxn947/clock_config.c rename to hw/bsp/mcx/boards/frdm_mcxn947/clock_config.c diff --git a/hw/bsp/mcx/boards/frdmmcxn947/clock_config.h b/hw/bsp/mcx/boards/frdm_mcxn947/clock_config.h similarity index 100% rename from hw/bsp/mcx/boards/frdmmcxn947/clock_config.h rename to hw/bsp/mcx/boards/frdm_mcxn947/clock_config.h diff --git a/hw/bsp/mcx/boards/frdmmcxn947/pin_mux.c b/hw/bsp/mcx/boards/frdm_mcxn947/pin_mux.c similarity index 100% rename from hw/bsp/mcx/boards/frdmmcxn947/pin_mux.c rename to hw/bsp/mcx/boards/frdm_mcxn947/pin_mux.c diff --git a/hw/bsp/mcx/boards/frdmmcxn947/pin_mux.h b/hw/bsp/mcx/boards/frdm_mcxn947/pin_mux.h similarity index 100% rename from hw/bsp/mcx/boards/frdmmcxn947/pin_mux.h rename to hw/bsp/mcx/boards/frdm_mcxn947/pin_mux.h From c97c3418c741a26666942e184ca514f5dbdafcfa Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 5 Apr 2024 20:31:55 +0700 Subject: [PATCH 239/454] minor update bsp --- .../build_system/cmake/cpu/cortex-m23.cmake | 4 +- .../cmake/cpu/cortex-m33-nodsp-nofp.cmake | 2 +- .../build_system/cmake/cpu/cortex-m33.cmake | 2 +- hw/bsp/mcx/boards/frdm_mcxa153/board.cmake | 3 - hw/bsp/mcx/boards/frdm_mcxa153/board.h | 20 ++-- hw/bsp/mcx/boards/frdm_mcxa153/board.mk | 2 +- hw/bsp/mcx/boards/frdm_mcxn947/board.cmake | 3 - hw/bsp/mcx/boards/frdm_mcxn947/board.mk | 2 +- hw/bsp/mcx/boards/mcxn947brk/board.cmake | 3 - hw/bsp/mcx/boards/mcxn947brk/board.mk | 2 +- hw/bsp/mcx/family.c | 92 +++++++++---------- hw/bsp/mcx/family.cmake | 10 ++ hw/bsp/mcx/family.mk | 15 +-- src/portable/chipidea/ci_fs/ci_fs_mcx.h | 20 ++-- src/portable/chipidea/ci_fs/dcd_ci_fs.c | 2 +- 15 files changed, 81 insertions(+), 101 deletions(-) diff --git a/examples/build_system/cmake/cpu/cortex-m23.cmake b/examples/build_system/cmake/cpu/cortex-m23.cmake index 3093dc99a..c7ce1d242 100644 --- a/examples/build_system/cmake/cpu/cortex-m23.cmake +++ b/examples/build_system/cmake/cpu/cortex-m23.cmake @@ -5,13 +5,13 @@ if (TOOLCHAIN STREQUAL "gcc") -mfloat-abi=soft ) - set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") + set(FREERTOS_PORT GCC_ARM_CM23_NTZ_NONSECURE CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "iar") set(TOOLCHAIN_COMMON_FLAGS --cpu cortex-m23 ) - set(FREERTOS_PORT IAR_ARM_CM0 CACHE INTERNAL "") + set(FREERTOS_PORT IAR_ARM_CM23_NTZ_NONSECURE CACHE INTERNAL "") endif () diff --git a/examples/build_system/cmake/cpu/cortex-m33-nodsp-nofp.cmake b/examples/build_system/cmake/cpu/cortex-m33-nodsp-nofp.cmake index 7946affbe..01e6b979a 100644 --- a/examples/build_system/cmake/cpu/cortex-m33-nodsp-nofp.cmake +++ b/examples/build_system/cmake/cpu/cortex-m33-nodsp-nofp.cmake @@ -12,6 +12,6 @@ elseif (TOOLCHAIN STREQUAL "iar") --cpu cortex-m33+nodsp ) - set(FREERTOS_PORT IAR_ARM_CM4F CACHE INTERNAL "") + set(FREERTOS_PORT IAR_ARM_CM33_NTZ_NONSECURE CACHE INTERNAL "") endif () diff --git a/examples/build_system/cmake/cpu/cortex-m33.cmake b/examples/build_system/cmake/cpu/cortex-m33.cmake index 7ebaf1748..94c29099d 100644 --- a/examples/build_system/cmake/cpu/cortex-m33.cmake +++ b/examples/build_system/cmake/cpu/cortex-m33.cmake @@ -14,6 +14,6 @@ elseif (TOOLCHAIN STREQUAL "iar") --fpu VFPv5-SP ) - set(FREERTOS_PORT IAR_ARM_CM4F CACHE INTERNAL "") + set(FREERTOS_PORT IAR_ARM_CM33_NTZ_NONSECURE CACHE INTERNAL "") endif () diff --git a/hw/bsp/mcx/boards/frdm_mcxa153/board.cmake b/hw/bsp/mcx/boards/frdm_mcxa153/board.cmake index acde3f46f..6a9a20e21 100644 --- a/hw/bsp/mcx/boards/frdm_mcxa153/board.cmake +++ b/hw/bsp/mcx/boards/frdm_mcxa153/board.cmake @@ -1,9 +1,6 @@ set(MCU_VARIANT MCXA153) set(MCU_CORE MCXA153) -set(FAMILY_MCUS MCXA15 CACHE INTERNAL "") -set(CMAKE_SYSTEM_PROCESSOR cortex-m33-nodsp-nofp CACHE INTERNAL "System Processor") - set(JLINK_DEVICE MCXA153_M33) set(PYOCD_TARGET MCXA153) set(NXPLINK_DEVICE MCXA153:MCXA153) diff --git a/hw/bsp/mcx/boards/frdm_mcxa153/board.h b/hw/bsp/mcx/boards/frdm_mcxa153/board.h index 02a452da5..e207d89d9 100644 --- a/hw/bsp/mcx/boards/frdm_mcxa153/board.h +++ b/hw/bsp/mcx/boards/frdm_mcxa153/board.h @@ -28,7 +28,7 @@ #define BOARD_H_ #ifdef __cplusplus - extern "C" { +extern "C" { #endif // LED @@ -38,29 +38,27 @@ #define LED_STATE_ON 0 // ISP button (Dummy, use unused pin - #define BUTTON_GPIO GPIO3 - #define BUTTON_CLK kCLOCK_GateGPIO3 - #define BUTTON_PIN 29 //sw2 - #define BUTTON_STATE_ACTIVE 0 +#define BUTTON_GPIO GPIO3 +#define BUTTON_CLK kCLOCK_GateGPIO3 +#define BUTTON_PIN 29 //sw2 +#define BUTTON_STATE_ACTIVE 0 // UART #define UART_DEV LPUART0 static inline void board_uart_init_clock(void) { - /* attach 12 MHz clock to LPUART0 (debug console) */ - CLOCK_SetClockDiv(kCLOCK_DivLPUART0, 1u); - CLOCK_AttachClk(kFRO12M_to_LPUART0); + CLOCK_SetClockDiv(kCLOCK_DivLPUART0, 1u); + CLOCK_AttachClk(kFRO12M_to_LPUART0); - RESET_PeripheralReset(kLPUART0_RST_SHIFT_RSTn); + RESET_PeripheralReset(kLPUART0_RST_SHIFT_RSTn); } - // XTAL #define XTAL0_CLK_HZ (24 * 1000 * 1000U) #ifdef __cplusplus - } +} #endif #endif diff --git a/hw/bsp/mcx/boards/frdm_mcxa153/board.mk b/hw/bsp/mcx/boards/frdm_mcxa153/board.mk index cf6d9c0eb..af8416d8e 100644 --- a/hw/bsp/mcx/boards/frdm_mcxa153/board.mk +++ b/hw/bsp/mcx/boards/frdm_mcxa153/board.mk @@ -2,7 +2,7 @@ MCU_VARIANT = MCXA153 MCU_CORE = MCXA153 PORT = 0 -CPU_CORE ?= cortex-m33-nodsp-nofp +CPU_CORE = cortex-m33-nodsp-nofp CFLAGS += \ -DCPU_MCXA153VLH \ -DCFG_TUSB_MCU=OPT_MCU_MCXA15 \ diff --git a/hw/bsp/mcx/boards/frdm_mcxn947/board.cmake b/hw/bsp/mcx/boards/frdm_mcxn947/board.cmake index a08d248f5..8c3280743 100644 --- a/hw/bsp/mcx/boards/frdm_mcxn947/board.cmake +++ b/hw/bsp/mcx/boards/frdm_mcxn947/board.cmake @@ -1,9 +1,6 @@ set(MCU_VARIANT MCXN947) set(MCU_CORE MCXN947_cm33_core0) -set(CMAKE_SYSTEM_PROCESSOR cortex-m33 CACHE INTERNAL "System Processor") -set(FAMILY_MCUS MCXN9 CACHE INTERNAL "") - set(JLINK_DEVICE MCXN947_M33_0) set(PYOCD_TARGET MCXN947) set(NXPLINK_DEVICE MCXN947:MCXN947) diff --git a/hw/bsp/mcx/boards/frdm_mcxn947/board.mk b/hw/bsp/mcx/boards/frdm_mcxn947/board.mk index d90780996..22fefd79b 100644 --- a/hw/bsp/mcx/boards/frdm_mcxn947/board.mk +++ b/hw/bsp/mcx/boards/frdm_mcxn947/board.mk @@ -2,7 +2,7 @@ MCU_VARIANT = MCXN947 MCU_CORE = MCXN947_cm33_core0 PORT ?= 1 -CPU_CORE ?= cortex-m33 +CPU_CORE = cortex-m33 CFLAGS += \ -DCPU_MCXN947VDF_cm33_core0 \ -DCFG_TUSB_MCU=OPT_MCU_MCXN9 \ diff --git a/hw/bsp/mcx/boards/mcxn947brk/board.cmake b/hw/bsp/mcx/boards/mcxn947brk/board.cmake index a08d248f5..8c3280743 100644 --- a/hw/bsp/mcx/boards/mcxn947brk/board.cmake +++ b/hw/bsp/mcx/boards/mcxn947brk/board.cmake @@ -1,9 +1,6 @@ set(MCU_VARIANT MCXN947) set(MCU_CORE MCXN947_cm33_core0) -set(CMAKE_SYSTEM_PROCESSOR cortex-m33 CACHE INTERNAL "System Processor") -set(FAMILY_MCUS MCXN9 CACHE INTERNAL "") - set(JLINK_DEVICE MCXN947_M33_0) set(PYOCD_TARGET MCXN947) set(NXPLINK_DEVICE MCXN947:MCXN947) diff --git a/hw/bsp/mcx/boards/mcxn947brk/board.mk b/hw/bsp/mcx/boards/mcxn947brk/board.mk index d90780996..22fefd79b 100644 --- a/hw/bsp/mcx/boards/mcxn947brk/board.mk +++ b/hw/bsp/mcx/boards/mcxn947brk/board.mk @@ -2,7 +2,7 @@ MCU_VARIANT = MCXN947 MCU_CORE = MCXN947_cm33_core0 PORT ?= 1 -CPU_CORE ?= cortex-m33 +CPU_CORE = cortex-m33 CFLAGS += \ -DCPU_MCXN947VDF_cm33_core0 \ -DCFG_TUSB_MCU=OPT_MCU_MCXN9 \ diff --git a/hw/bsp/mcx/family.c b/hw/bsp/mcx/family.c index 96ae2fde3..cc675a49d 100644 --- a/hw/bsp/mcx/family.c +++ b/hw/bsp/mcx/family.c @@ -33,6 +33,10 @@ #include "pin_mux.h" #include "clock_config.h" +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM +//--------------------------------------------------------------------+ + #ifdef BOARD_TUD_RHPORT #define PORT_SUPPORT_DEVICE(_n) (BOARD_TUD_RHPORT == _n) #else @@ -45,54 +49,50 @@ #define PORT_SUPPORT_HOST(_n) 0 #endif -//--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM -//--------------------------------------------------------------------+ - //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ #if CFG_TUSB_MCU == OPT_MCU_MCXN9 -void USB0_FS_IRQHandler(void) -{ +void USB0_FS_IRQHandler(void) { tud_int_handler(0); } -void USB1_HS_IRQHandler(void) -{ +void USB1_HS_IRQHandler(void) { tud_int_handler(1); } #elif CFG_TUSB_MCU == OPT_MCU_MCXA15 -void USB0_IRQHandler(void) -{ + +void USB0_IRQHandler(void) { tud_int_handler(0); } + #endif -void board_init(void) -{ +void board_init(void) { BOARD_InitPins(); BOARD_InitBootClocks(); CLOCK_SetupExtClocking(XTAL0_CLK_HZ); +#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 // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) - NVIC_SetPriority(USB1_HS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); + #if CFG_TUSB_MCU == OPT_MCU_MCXN9 + NVIC_SetPriority(USB0_FS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); + NVIC_SetPriority(USB1_HS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); + #else + NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); + #endif #endif // LED CLOCK_EnableClock(LED_CLK); - gpio_pin_config_t led_config = { - kGPIO_DigitalOutput, - 0, - }; - GPIO_PinInit(LED_GPIO,LED_PIN, &led_config); + gpio_pin_config_t led_config = {kGPIO_DigitalOutput, 0}; + GPIO_PinInit(LED_GPIO, LED_PIN, &led_config); board_led_write(0); #ifdef NEOPIXEL_PIN @@ -110,7 +110,7 @@ void board_init(void) // Button #ifdef BUTTON_GPIO CLOCK_EnableClock(BUTTON_CLK); - gpio_pin_config_t const button_config = { kGPIO_DigitalInput, 0}; + gpio_pin_config_t const button_config = {kGPIO_DigitalInput, 0}; GPIO_PinInit(BUTTON_GPIO, BUTTON_PIN, &button_config); #endif @@ -125,33 +125,26 @@ void board_init(void) 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; + uart_config.enableTx = true; + uart_config.enableRx = true; LPUART_Init(UART_DEV, &uart_config, 12000000u); #endif // USB VBUS /* PORT0 PIN22 configured as USB0_VBUS */ - - /* MCXA15 USB configurations */ -#if PORT_SUPPORT_DEVICE(0) && (CFG_TUSB_MCU == OPT_MCU_MCXA15) - - RESET_PeripheralReset(kUSB0_RST_SHIFT_RSTn); - CLOCK_EnableUsbfsClock(); - -#endif - - - /* MCXN9 USB configurations */ -#if PORT_SUPPORT_DEVICE(0) && (CFG_TUSB_MCU == OPT_MCU_MCXN9) +#if PORT_SUPPORT_DEVICE(0) // Port0 is Full Speed + #if CFG_TUSB_MCU == OPT_MCU_MCXA15 + RESET_PeripheralReset(kUSB0_RST_SHIFT_RSTn); + #elif CFG_TUSB_MCU == OPT_MCU_MCXN9 CLOCK_AttachClk(kCLK_48M_to_USB0); CLOCK_EnableClock(kCLOCK_Usb0Ram); CLOCK_EnableClock(kCLOCK_Usb0Fs); - CLOCK_EnableUsbfsClock(); + #endif + CLOCK_EnableUsbfsClock(); #endif #if PORT_SUPPORT_DEVICE(1) && (CFG_TUSB_MCU == OPT_MCU_MCXN9) @@ -213,9 +206,8 @@ void board_init(void) // Board porting API //--------------------------------------------------------------------+ -void board_led_write(bool state) -{ - GPIO_PinWrite(LED_GPIO, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +void board_led_write(bool state) { + GPIO_PinWrite(LED_GPIO, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); #ifdef NEOPIXEL_PIN if (state) { @@ -229,23 +221,21 @@ void board_led_write(bool state) #endif } -uint32_t board_button_read(void) -{ +uint32_t board_button_read(void) { #ifdef BUTTON_GPIO return BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_GPIO, BUTTON_PIN); #endif } -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 - LPUART_WriteBlocking(UART_DEV, (uint8_t const *) buf, len); + LPUART_WriteBlocking(UART_DEV, (uint8_t const*) buf, len); return len; #else (void) buf; (void) len; @@ -255,13 +245,13 @@ int board_uart_write(void const * 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/mcx/family.cmake b/hw/bsp/mcx/family.cmake index 78490ec57..c8591b569 100644 --- a/hw/bsp/mcx/family.cmake +++ b/hw/bsp/mcx/family.cmake @@ -11,6 +11,16 @@ set(CMSIS_DIR ${TOP}/lib/CMSIS_5) include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up +if (MCU_VARIANT STREQUAL "MCXA153") + set(CMAKE_SYSTEM_PROCESSOR cortex-m33-nodsp-nofp CACHE INTERNAL "System Processor") + set(FAMILY_MCUS MCXA15 CACHE INTERNAL "") +elseif (MCU_VARIANT STREQUAL "MCXN947") + set(CMAKE_SYSTEM_PROCESSOR cortex-m33 CACHE INTERNAL "System Processor") + set(FAMILY_MCUS MCXN9 CACHE INTERNAL "") +else() + message(FATAL_ERROR "MCU_VARIANT not supported") +endif() + set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) #------------------------------------ diff --git a/hw/bsp/mcx/family.mk b/hw/bsp/mcx/family.mk index 3ee0efaf6..58149fb8d 100644 --- a/hw/bsp/mcx/family.mk +++ b/hw/bsp/mcx/family.mk @@ -39,23 +39,16 @@ SRC_C += \ $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_lpuart.c \ $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_common_arm.c \ - -# fsl_lpflexcomm just needed for MCXN9 +# fsl_lpflexcomm for MCXN9 ifeq ($(MCU_VARIANT), MCXN947) - SRC_C += \ - $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_lpflexcomm.c \ - + SRC_C += $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_lpflexcomm.c endif -# fsl_spc just needed for MCXNA15 +# fsl_spc for MCXNA15 ifeq ($(MCU_VARIANT), MCXA153) - SRC_C += \ - $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_spc.c \ - + SRC_C += $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_spc.c endif - - INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ diff --git a/src/portable/chipidea/ci_fs/ci_fs_mcx.h b/src/portable/chipidea/ci_fs/ci_fs_mcx.h index 3f2b13323..4b93a03a7 100644 --- a/src/portable/chipidea/ci_fs/ci_fs_mcx.h +++ b/src/portable/chipidea/ci_fs/ci_fs_mcx.h @@ -30,29 +30,27 @@ #include "fsl_device_registers.h" #if CFG_TUSB_MCU == OPT_MCU_MCXN9 - #define CI_FS_REG(_port) ((ci_fs_regs_t*) USBFS0_BASE) - #define USB0_IRQN USB0_FS_IRQn + #define CI_FS_REG(_port) ((ci_fs_regs_t*) USBFS0_BASE) + #define CIFS_IRQN USB0_FS_IRQn #elif CFG_TUSB_MCU == OPT_MCU_MCXA15 - #define CI_FS_REG(_port) ((ci_fs_regs_t*) USB0_BASE) - #define USB0_IRQN USB0_IRQn + #define CI_FS_REG(_port) ((ci_fs_regs_t*) USB0_BASE) + #define CIFS_IRQN USB0_IRQn #else #error "MCU is not supported" #endif -#define CI_REG CI_FS_REG(0) +#define CI_REG CI_FS_REG(0) -void dcd_int_enable(uint8_t rhport) -{ +void dcd_int_enable(uint8_t rhport) { (void) rhport; - NVIC_EnableIRQ(USB0_IRQN); + NVIC_EnableIRQ(CIFS_IRQN); } -void dcd_int_disable(uint8_t rhport) -{ +void dcd_int_disable(uint8_t rhport) { (void) rhport; - NVIC_DisableIRQ(USB0_IRQN); + NVIC_DisableIRQ(CIFS_IRQN); } #endif diff --git a/src/portable/chipidea/ci_fs/dcd_ci_fs.c b/src/portable/chipidea/ci_fs/dcd_ci_fs.c index a68ecf8c9..02f813ab5 100644 --- a/src/portable/chipidea/ci_fs/dcd_ci_fs.c +++ b/src/portable/chipidea/ci_fs/dcd_ci_fs.c @@ -295,7 +295,7 @@ void dcd_init(uint8_t rhport) CI_REG->INT_EN = USB_INTEN_USBRSTEN_MASK; dcd_connect(rhport); - // NVIC_ClearPendingIRQ(USB0_IRQn); + // NVIC_ClearPendingIRQ(CIFS_IRQN); } void dcd_set_address(uint8_t rhport, uint8_t dev_addr) From e160366a1e3fc26242daf0e31c0d0fafcc51b83c Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 5 Apr 2024 19:12:28 +0200 Subject: [PATCH 240/454] dwc2: remove fifo free code. --- src/portable/synopsys/dwc2/dcd_dwc2.c | 43 --------------------------- 1 file changed, 43 deletions(-) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index cf8f3be50..8b13b0753 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -97,7 +97,6 @@ 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) -static bool _out_ep_closed; // Flag to check if RX FIFO size needs an update (reduce its size) // SOF enabling flag - required for SOF to not get disabled in ISR when SOF was enabled by static bool _sof_en; @@ -113,20 +112,6 @@ 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; } -static void update_grxfsiz(uint8_t rhport) { - dwc2_regs_t* dwc2 = DWC2_REG(rhport); - uint8_t const ep_count = _dwc2_controller[rhport].ep_count; - - // Determine largest EP size for RX FIFO - uint16_t max_epsize = 0; - for (uint8_t epnum = 0; epnum < ep_count; epnum++) { - max_epsize = tu_max16(max_epsize, xfer_status[epnum][TUSB_DIR_OUT].max_size); - } - - // Update size of RX FIFO - dwc2->grxfsiz = calc_grxfsiz(max_epsize, ep_count); -} - static bool fifo_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; @@ -268,7 +253,6 @@ static void bus_reset(uint8_t rhport) { uint8_t const ep_count = _dwc2_controller[rhport].ep_count; tu_memclr(xfer_status, sizeof(xfer_status)); - _out_ep_closed = false; _sof_en = false; @@ -791,26 +775,7 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t* ff, uint16_t } void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { - 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); - edpt_disable(rhport, ep_addr, false); - - // Update max_size - xfer_status[epnum][dir].max_size = 0; // max_size = 0 marks a disabled EP - required for changing FIFO allocation - - if (dir == TUSB_DIR_IN) { - uint16_t const fifo_size = (dwc2->dieptxf[epnum - 1] & DIEPTXF_INEPTXFD_Msk) >> DIEPTXF_INEPTXFD_Pos; - uint16_t const fifo_start = (dwc2->dieptxf[epnum - 1] & DIEPTXF_INEPTXSA_Msk) >> DIEPTXF_INEPTXSA_Pos; - - // For now only the last opened endpoint can be closed without fuss. - TU_ASSERT(fifo_start == _dwc2_controller[rhport].ep_fifo_size / 4 - _allocated_fifo_words_tx,); - _allocated_fifo_words_tx -= fifo_size; - } else { - _out_ep_closed = true; // Set flag such that RX FIFO gets reduced in size once RX FIFO is empty - } } void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { @@ -1181,14 +1146,6 @@ void dcd_int_handler(uint8_t rhport) { handle_rxflvl_irq(rhport); } while (dwc2->gotgint & GINTSTS_RXFLVL); - // Manage RX FIFO size - if (_out_ep_closed) { - update_grxfsiz(rhport); - - // Disable flag - _out_ep_closed = false; - } - dwc2->gintmsk |= GINTMSK_RXFLVLM; } From dd3db9cc0c68f186caab10ff6cb66e42d75a215d Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 6 Apr 2024 00:18:51 +0700 Subject: [PATCH 241/454] fix ra2a1 fpu with freertos --- hw/bsp/ra/FreeRTOSConfig/FreeRTOSConfig.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/hw/bsp/ra/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/ra/FreeRTOSConfig/FreeRTOSConfig.h index 57ed3a9e4..ce70efbf3 100644 --- a/hw/bsp/ra/FreeRTOSConfig/FreeRTOSConfig.h +++ b/hw/bsp/ra/FreeRTOSConfig/FreeRTOSConfig.h @@ -64,7 +64,13 @@ /* 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) From e642066562f96e7e4790b709635d32d4c8450861 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sat, 6 Apr 2024 19:02:50 +0200 Subject: [PATCH 242/454] Move TUP_DCD_EDPT_ISO_ALLOC outside usbd_edpt_close() loop. --- src/class/video/video_device.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index 648c8c3c8..891ece721 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -755,6 +755,7 @@ static bool _open_vs_itf(uint8_t rhport, videod_streaming_interface_t *stm, uint TU_LOG_DRV(" reopen VS %d\r\n", altnum); uint8_t const *desc = _videod_itf[stm->index_vc].beg; +#ifndef TUP_DCD_EDPT_ISO_ALLOC /* Close endpoints of previous settings. */ for (i = 0; i < TU_ARRAY_SIZE(stm->desc.ep); ++i) { uint_fast16_t ofs_ep = stm->desc.ep[i]; @@ -762,13 +763,12 @@ static bool _open_vs_itf(uint8_t rhport, videod_streaming_interface_t *stm, uint tusb_desc_endpoint_t const *ep = (tusb_desc_endpoint_t const*)(desc + ofs_ep); /* Only ISO endpoints needs to be closed */ if(ep->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) { -#ifndef TUP_DCD_EDPT_ISO_ALLOC usbd_edpt_close(rhport, ep->bEndpointAddress); -#endif stm->desc.ep[i] = 0; TU_LOG_DRV(" close EP%02x\r\n", ep->bEndpointAddress); } } +#endif /* clear transfer management information */ stm->buffer = NULL; From 7f7dca7b15971ab83f07f4d930a95117e8bcc78e Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 8 Apr 2024 11:04:15 +0700 Subject: [PATCH 243/454] fix configENABLE_FPU=0 for cortex-m33+nodsp --- hw/bsp/mcx/FreeRTOSConfig/FreeRTOSConfig.h | 6 +++++- hw/bsp/ra/FreeRTOSConfig/FreeRTOSConfig.h | 6 ++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/hw/bsp/mcx/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/mcx/FreeRTOSConfig/FreeRTOSConfig.h index 6f10a7ab0..5bf990bab 100644 --- a/hw/bsp/mcx/FreeRTOSConfig/FreeRTOSConfig.h +++ b/hw/bsp/mcx/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/ra/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/ra/FreeRTOSConfig/FreeRTOSConfig.h index ce70efbf3..b132e2559 100644 --- a/hw/bsp/ra/FreeRTOSConfig/FreeRTOSConfig.h +++ b/hw/bsp/ra/FreeRTOSConfig/FreeRTOSConfig.h @@ -64,13 +64,11 @@ /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 - #if defined(__ARM_FP) && __ARM_FP >= 4 -#define configENABLE_FPU 1 + #define configENABLE_FPU 1 #else -#define configENABLE_FPU 0 + #define configENABLE_FPU 0 #endif - #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) From d6d8acad90c8a1578dcbd886154fbb3f2bd1a363 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 8 Apr 2024 11:15:21 +0700 Subject: [PATCH 244/454] add CFG_EXAMPLE_VIDEO_READONLY for mcxa15 --- hw/bsp/mcx/boards/frdm_mcxa153/board.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/bsp/mcx/boards/frdm_mcxa153/board.cmake b/hw/bsp/mcx/boards/frdm_mcxa153/board.cmake index 6a9a20e21..7cd8991e6 100644 --- a/hw/bsp/mcx/boards/frdm_mcxa153/board.cmake +++ b/hw/bsp/mcx/boards/frdm_mcxa153/board.cmake @@ -12,6 +12,7 @@ function(update_board TARGET) CPU_MCXA153VLH BOARD_TUD_RHPORT=0 BOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED + CFG_EXAMPLE_VIDEO_READONLY ) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/clock_config.c From cbbfbbb57ea8b4ea97ce4f2e2d157da9c25019fe Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 8 Apr 2024 13:16:08 +0700 Subject: [PATCH 245/454] add cpuctl and pinctl to tuh_configure() option for max3421 --- .github/workflows/build_iar.yml | 1 + src/host/usbh.h | 10 +++++++--- src/portable/analog/max3421/hcd_max3421.c | 18 +++++++++++------- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build_iar.yml b/.github/workflows/build_iar.yml index a0a022ecc..499349904 100644 --- a/.github/workflows/build_iar.yml +++ b/.github/workflows/build_iar.yml @@ -28,6 +28,7 @@ concurrency: jobs: cmake: + if: github.repository_owner == 'hathach' runs-on: [self-hosted, Linux, X64, hifiphile] strategy: fail-fast: false diff --git a/src/host/usbh.h b/src/host/usbh.h index 57362c778..359684169 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -80,12 +80,16 @@ enum { TUH_CFGID_MAX3421 = 200, }; +typedef struct { + uint8_t max_nak; // max NAK per endpoint per frame + uint8_t cpuctl; // R16: CPU Control Register + uint8_t pinctl; // R17: Pin Control Register. FDUPSPI bit is ignored +} tuh_configure_max3421_t; + typedef union { // For TUH_CFGID_RPI_PIO_USB_CONFIGURATION use pio_usb_configuration_t - struct { - uint8_t max_nak; - } max3421; + tuh_configure_max3421_t max3421; } tuh_configure_param_t; //--------------------------------------------------------------------+ diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index 059f674cd..39afb7505 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -233,7 +233,11 @@ typedef struct { static max3421_data_t _hcd_data; // max NAK before giving up in a frame. 0 means infinite NAKs -static uint8_t _max_nak = MAX_NAK_DEFAULT; +static tuh_configure_max3421_t _tuh_cfg = { + .max_nak = MAX_NAK_DEFAULT, + .cpuctl = 0, // default: INT pulse width = 10.6 us + .pinctl = 0, // default: negative edge interrupt +}; //--------------------------------------------------------------------+ // API: SPI transfer with MAX3421E @@ -416,7 +420,7 @@ static void free_ep(uint8_t daddr) { 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) && - (_max_nak == 0 || state < EP_STATE_ATTEMPT_1 + _max_nak); + (_tuh_cfg.max_nak == 0 || state < EP_STATE_ATTEMPT_1 + _tuh_cfg.max_nak); } // Find the next pending endpoint using round-robin scheduling, starting from next endpoint. @@ -454,7 +458,7 @@ bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) { TU_VERIFY(cfg_id == TUH_CFGID_MAX3421 && cfg_param != NULL); tuh_configure_param_t const* cfg = (tuh_configure_param_t const*) cfg_param; - _max_nak = tu_min8(cfg->max3421.max_nak, EP_STATE_ATTEMPT_MAX-EP_STATE_ATTEMPT_1); + _tuh_cfg = cfg->max3421; return true; } @@ -476,7 +480,7 @@ bool hcd_init(uint8_t rhport) { #endif // full duplex, interrupt negative edge - reg_write(rhport, PINCTL_ADDR, PINCTL_FDUPSPI, false); + reg_write(rhport, PINCTL_ADDR, _tuh_cfg.pinctl | PINCTL_FDUPSPI, false); // v1 is 0x01, v2 is 0x12, v3 is 0x13 uint8_t const revision = reg_read(rhport, REVISION_ADDR, false); @@ -505,7 +509,7 @@ bool hcd_init(uint8_t rhport) { tuh_max3421_int_api(rhport, true); // Enable Interrupt pin - reg_write(rhport, CPUCTL_ADDR, CPUCTL_IE, false); + reg_write(rhport, CPUCTL_ADDR, _tuh_cfg.cpuctl | CPUCTL_IE, false); return true; } @@ -516,9 +520,9 @@ bool hcd_deinit(uint8_t rhport) { // disable interrupt tuh_max3421_int_api(rhport, false); - // reset max3421 + // reset max3421 and power down reg_write(rhport, USBCTL_ADDR, USBCTL_CHIPRES, false); - reg_write(rhport, USBCTL_ADDR, 0, false); + reg_write(rhport, USBCTL_ADDR, USBCTL_PWRDOWN, false); #if OSAL_MUTEX_REQUIRED osal_mutex_delete(_hcd_data.spi_mutex); From 47c12a07f2edf927eaa685ee8c32b222271d770f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20=22xq=22=20Quei=C3=9Fner?= Date: Mon, 2 Jan 2023 17:09:45 +0100 Subject: [PATCH 246/454] Implements tuh_deinit() and tud_deinit() to uninitialize host/device mode. --- src/device/dcd.h | 3 +++ src/device/usbd.h | 5 ++++- src/portable/raspberrypi/rp2040/dcd_rp2040.c | 12 ++++++++++++ src/portable/raspberrypi/rp2040/hcd_rp2040.c | 8 ++++++++ 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/device/dcd.h b/src/device/dcd.h index 69c26bcf4..21f404e4f 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -122,6 +122,9 @@ void dcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) TU_ATTR_W // Initialize controller to device mode void dcd_init(uint8_t rhport); +// Deinitialize controller, unset device mode. +void dcd_deinit(uint8_t rhport); + // Interrupt Handler void dcd_int_handler(uint8_t rhport); diff --git a/src/device/usbd.h b/src/device/usbd.h index 2e3987b99..a9350192b 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -37,9 +37,12 @@ extern "C" { // Application API //--------------------------------------------------------------------+ -// Init device stack +// Init device stack on roothub port bool tud_init (uint8_t rhport); +// Deinit device stack on roothub port +void tud_deinit(uint8_t rhport); + // Check if device stack is already initialized bool tud_inited(void); diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index 5c564cb1c..ccc7ee102 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -407,6 +407,18 @@ void dcd_init(uint8_t rhport) { dcd_connect(rhport); } +void dcd_deinit(uint8_t rhport) { + assert(rhport == 0); + + dcd_disconnect(rhport); + reset_non_control_endpoints(); + irq_remove_handler(USBCTRL_IRQ, dcd_rp2040_irq); + + // reset usb hardware into initial state + reset_block(RESETS_RESET_USBCTRL_BITS); + unreset_block_wait(RESETS_RESET_USBCTRL_BITS); +} + void dcd_int_enable(__unused uint8_t rhport) { assert(rhport == 0); irq_set_enabled(USBCTRL_IRQ, true); diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index b351a9a07..762753a25 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -409,6 +409,14 @@ bool hcd_init(uint8_t rhport) return true; } +void hcd_deinit(uint8_t rhport) { + (void) rhport; + + irq_remove_handler(USBCTRL_IRQ, hcd_rp2040_irq); + reset_block(RESETS_RESET_USBCTRL_BITS); + unreset_block_wait(RESETS_RESET_USBCTRL_BITS); +} + void hcd_port_reset(uint8_t rhport) { (void) rhport; From c3c06484560d0102366a3a1b1101c35301009f97 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 8 Apr 2024 22:07:56 +0700 Subject: [PATCH 247/454] add class driver deinit --- src/class/audio/audio_device.c | 4 + src/class/audio/audio_device.h | 1 + src/class/bth/bth_device.c | 7 +- src/class/bth/bth_device.h | 1 + src/class/cdc/cdc_device.c | 32 ++- src/class/cdc/cdc_device.h | 1 + src/class/dfu/dfu_device.c | 7 +- src/class/dfu/dfu_device.h | 1 + src/class/dfu/dfu_rt_device.c | 7 +- src/class/dfu/dfu_rt_device.h | 1 + src/class/hid/hid_device.c | 7 +- src/class/hid/hid_device.h | 1 + src/class/midi/midi_device.c | 36 +++- src/class/midi/midi_device.h | 1 + src/class/msc/msc_device.c | 8 +- src/class/msc/msc_device.h | 1 + src/class/net/ecm_rndis_device.c | 7 +- src/class/net/ncm_device.c | 4 + src/class/net/net_device.h | 1 + src/class/usbtmc/usbtmc_device.c | 5 + src/class/usbtmc/usbtmc_device.h | 3 +- src/class/vendor/vendor_device.c | 38 +++- src/class/vendor/vendor_device.h | 1 + src/class/video/video_device.c | 4 + src/class/video/video_device.h | 1 + src/device/dcd.h | 2 +- src/device/usbd.c | 204 ++++++++++++------- src/device/usbd.h | 2 +- src/device/usbd_pvt.h | 4 +- src/host/usbh.c | 2 +- src/portable/raspberrypi/rp2040/dcd_rp2040.c | 5 +- src/portable/raspberrypi/rp2040/hcd_rp2040.c | 4 +- src/tusb_option.h | 2 +- 33 files changed, 292 insertions(+), 113 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 9a361419b..7077d66f8 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -1396,6 +1396,10 @@ void audiod_init(void) } } +bool audiod_deinit(void) { + return false; // TODO not implemented yet +} + void audiod_reset(uint8_t rhport) { (void) rhport; diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index 040a760d6..b16514fd4 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -685,6 +685,7 @@ static inline bool tud_audio_fb_set(uint32_t feedback) // Internal Class Driver API //--------------------------------------------------------------------+ void audiod_init (void); +bool audiod_deinit (void); void audiod_reset (uint8_t rhport); uint16_t audiod_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool audiod_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); diff --git a/src/class/bth/bth_device.c b/src/class/bth/bth_device.c index f145e2ead..cbf6e1332 100755 --- a/src/class/bth/bth_device.c +++ b/src/class/bth/bth_device.c @@ -91,11 +91,14 @@ bool tud_bt_acl_data_send(void *event, uint16_t event_len) //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ -void btd_init(void) -{ +void btd_init(void) { tu_memclr(&_btd_itf, sizeof(_btd_itf)); } +bool btd_deinit(void) { + return true; +} + void btd_reset(uint8_t rhport) { (void)rhport; diff --git a/src/class/bth/bth_device.h b/src/class/bth/bth_device.h index e782c532b..4f6350839 100755 --- a/src/class/bth/bth_device.h +++ b/src/class/bth/bth_device.h @@ -104,6 +104,7 @@ bool tud_bt_acl_data_send(void *acl_data, uint16_t data_len); // Internal Class Driver API //--------------------------------------------------------------------+ void btd_init (void); +bool btd_deinit (void); void btd_reset (uint8_t rhport); uint16_t btd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool btd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const *request); diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index c26264e60..7ef0530ec 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -253,11 +253,39 @@ void cdcd_init(void) // In this way, the most current data is prioritized. tu_fifo_config(&p_cdc->tx_ff, p_cdc->tx_ff_buf, TU_ARRAY_SIZE(p_cdc->tx_ff_buf), 1, true); - tu_fifo_config_mutex(&p_cdc->rx_ff, NULL, osal_mutex_create(&p_cdc->rx_ff_mutex)); - tu_fifo_config_mutex(&p_cdc->tx_ff, osal_mutex_create(&p_cdc->tx_ff_mutex), NULL); + #if OSAL_MUTEX_REQUIRED + osal_mutex_t mutex_rd = osal_mutex_create(&p_cdc->rx_ff_mutex); + osal_mutex_t mutex_wr = osal_mutex_create(&p_cdc->tx_ff_mutex); + TU_ASSERT(mutex_rd != NULL && mutex_wr != NULL, ); + + tu_fifo_config_mutex(&p_cdc->rx_ff, NULL, mutex_rd); + tu_fifo_config_mutex(&p_cdc->tx_ff, mutex_wr, NULL); + #endif } } +bool cdcd_deinit(void) { + #if OSAL_MUTEX_REQUIRED + for(uint8_t i=0; irx_ff.mutex_rd; + osal_mutex_t mutex_wr = p_cdc->tx_ff.mutex_wr; + + if (mutex_rd) { + osal_mutex_delete(mutex_rd); + tu_fifo_config_mutex(&p_cdc->rx_ff, NULL, NULL); + } + + if (mutex_wr) { + osal_mutex_delete(mutex_wr); + tu_fifo_config_mutex(&p_cdc->tx_ff, NULL, NULL); + } + } + #endif + + return true; +} + void cdcd_reset(uint8_t rhport) { (void) rhport; diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index a6e07aa5c..20e908451 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -247,6 +247,7 @@ static inline bool tud_cdc_write_clear(void) // INTERNAL USBD-CLASS DRIVER API //--------------------------------------------------------------------+ void cdcd_init (void); +bool cdcd_deinit (void); void cdcd_reset (uint8_t rhport); uint16_t cdcd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool cdcd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); diff --git a/src/class/dfu/dfu_device.c b/src/class/dfu/dfu_device.c index 3e7c13dea..71e7ac2b3 100644 --- a/src/class/dfu/dfu_device.c +++ b/src/class/dfu/dfu_device.c @@ -160,11 +160,14 @@ void dfu_moded_reset(uint8_t rhport) reset_state(); } -void dfu_moded_init(void) -{ +void dfu_moded_init(void) { dfu_moded_reset(0); } +bool dfu_moded_deinit(void) { + return true; +} + uint16_t dfu_moded_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) { (void) rhport; diff --git a/src/class/dfu/dfu_device.h b/src/class/dfu/dfu_device.h index fecf8596f..00c22ea8b 100644 --- a/src/class/dfu/dfu_device.h +++ b/src/class/dfu/dfu_device.h @@ -86,6 +86,7 @@ TU_ATTR_WEAK void tud_dfu_abort_cb(uint8_t alt); // Internal Class Driver API //--------------------------------------------------------------------+ void dfu_moded_init(void); +bool dfu_moded_deinit(void); void dfu_moded_reset(uint8_t rhport); uint16_t dfu_moded_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); diff --git a/src/class/dfu/dfu_rt_device.c b/src/class/dfu/dfu_rt_device.c index a940d8d62..3b801b787 100644 --- a/src/class/dfu/dfu_rt_device.c +++ b/src/class/dfu/dfu_rt_device.c @@ -51,8 +51,11 @@ //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ -void dfu_rtd_init(void) -{ +void dfu_rtd_init(void) { +} + +bool dfu_rtd_deinit(void) { + return true; } void dfu_rtd_reset(uint8_t rhport) diff --git a/src/class/dfu/dfu_rt_device.h b/src/class/dfu/dfu_rt_device.h index babaa8214..67eb26d95 100644 --- a/src/class/dfu/dfu_rt_device.h +++ b/src/class/dfu/dfu_rt_device.h @@ -43,6 +43,7 @@ void tud_dfu_runtime_reboot_to_dfu_cb(void); // Internal Class Driver API //--------------------------------------------------------------------+ void dfu_rtd_init(void); +bool dfu_rtd_deinit(void); void dfu_rtd_reset(uint8_t rhport); uint16_t dfu_rtd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool dfu_rtd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 5637ea6b4..e8eda1400 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -166,11 +166,14 @@ 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) { + return true; +} + void hidd_reset(uint8_t rhport) { (void) rhport; diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h index 17b24def1..53ecf9c06 100644 --- a/src/class/hid/hid_device.h +++ b/src/class/hid/hid_device.h @@ -406,6 +406,7 @@ static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y // Internal Class Driver API //--------------------------------------------------------------------+ void hidd_init (void); +bool hidd_deinit (void); void hidd_reset (uint8_t rhport); uint16_t hidd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c index 052372a93..42905ab0d 100644 --- a/src/class/midi/midi_device.c +++ b/src/class/midi/midi_device.c @@ -373,12 +373,10 @@ bool tud_midi_n_packet_write (uint8_t itf, uint8_t const packet[4]) //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ -void midid_init(void) -{ +void midid_init(void) { tu_memclr(_midid_itf, sizeof(_midid_itf)); - for(uint8_t i=0; itx_ff, midi->tx_ff_buf, CFG_TUD_MIDI_TX_BUFSIZE, 1, false); // OBVS. #if CFG_FIFO_MUTEX - tu_fifo_config_mutex(&midi->rx_ff, NULL, osal_mutex_create(&midi->rx_ff_mutex)); - tu_fifo_config_mutex(&midi->tx_ff, osal_mutex_create(&midi->tx_ff_mutex), NULL); + osal_mutex_t mutex_rd = osal_mutex_create(&midi->rx_ff_mutex); + osal_mutex_t mutex_wr = osal_mutex_create(&midi->tx_ff_mutex); + TU_ASSERT(mutex_wr != NULL && mutex_wr != NULL, ); + + tu_fifo_config_mutex(&midi->rx_ff, NULL, mutex_rd); + tu_fifo_config_mutex(&midi->tx_ff, mutex_wr, NULL); #endif } } +bool midid_deinit(void) { + #if CFG_FIFO_MUTEX + for(uint8_t i=0; irx_ff.mutex_rd; + osal_mutex_t mutex_wr = midi->tx_ff.mutex_wr; + + if (mutex_rd) { + osal_mutex_delete(mutex_rd); + tu_fifo_config_mutex(&midi->rx_ff, NULL, NULL); + } + + if (mutex_wr) { + osal_mutex_delete(mutex_wr); + tu_fifo_config_mutex(&midi->tx_ff, NULL, NULL); + } + } + #endif + + return true; +} + void midid_reset(uint8_t rhport) { (void) rhport; diff --git a/src/class/midi/midi_device.h b/src/class/midi/midi_device.h index 1c6f996be..3e89cc0a3 100644 --- a/src/class/midi/midi_device.h +++ b/src/class/midi/midi_device.h @@ -158,6 +158,7 @@ static inline bool tud_midi_packet_write (uint8_t const packet[4]) // Internal Class Driver API //--------------------------------------------------------------------+ void midid_init (void); +bool midid_deinit (void); void midid_reset (uint8_t rhport); uint16_t midid_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool midid_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index c145d86a6..588fcaaca 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -251,11 +251,15 @@ static inline void set_sense_medium_not_present(uint8_t lun) //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ -void mscd_init(void) -{ +void mscd_init(void) { tu_memclr(&_mscd_itf, sizeof(mscd_interface_t)); } +bool mscd_deinit(void) { + // nothing to do + return true; +} + void mscd_reset(uint8_t rhport) { (void) rhport; diff --git a/src/class/msc/msc_device.h b/src/class/msc/msc_device.h index 72f95be06..4247a40bd 100644 --- a/src/class/msc/msc_device.h +++ b/src/class/msc/msc_device.h @@ -150,6 +150,7 @@ TU_ATTR_WEAK bool tud_msc_is_writable_cb(uint8_t lun); // Internal Class Driver API //--------------------------------------------------------------------+ void mscd_init (void); +bool mscd_deinit (void); void mscd_reset (uint8_t rhport); uint16_t mscd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool mscd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * p_request); diff --git a/src/class/net/ecm_rndis_device.c b/src/class/net/ecm_rndis_device.c index 762425732..f7a5fd225 100644 --- a/src/class/net/ecm_rndis_device.c +++ b/src/class/net/ecm_rndis_device.c @@ -132,11 +132,14 @@ void netd_report(uint8_t *buf, uint16_t len) //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ -void netd_init(void) -{ +void netd_init(void) { tu_memclr(&_netd_itf, sizeof(_netd_itf)); } +bool netd_deinit(void) { + return true; +} + void netd_reset(uint8_t rhport) { (void) rhport; diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 226c42c4e..f84bd9f73 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -260,6 +260,10 @@ void netd_init(void) ncm_prepare_for_tx(); } +bool netd_deinit(void) { + return true; +} + void netd_reset(uint8_t rhport) { (void) rhport; diff --git a/src/class/net/net_device.h b/src/class/net/net_device.h index 399916355..da1a7b1e8 100644 --- a/src/class/net/net_device.h +++ b/src/class/net/net_device.h @@ -105,6 +105,7 @@ void tud_network_link_state_cb(bool state); // INTERNAL USBD-CLASS DRIVER API //--------------------------------------------------------------------+ void netd_init (void); +bool netd_deinit (void); void netd_reset (uint8_t rhport); uint16_t netd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool netd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 573654d58..972a450e6 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -260,6 +260,11 @@ void usbtmcd_init_cb(void) usbtmcLock = osal_mutex_create(&usbtmcLockBuffer); } +bool usbtmcd_deinit(void) { + osal_mutex_delete(usbtmcLock); + return true; +} + uint16_t usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) { (void)rhport; diff --git a/src/class/usbtmc/usbtmc_device.h b/src/class/usbtmc/usbtmc_device.h index c1298ddb8..3299a36eb 100644 --- a/src/class/usbtmc/usbtmc_device.h +++ b/src/class/usbtmc/usbtmc_device.h @@ -98,11 +98,12 @@ bool tud_usbtmc_start_bus_read(void); /* "callbacks" from USB device core */ +void usbtmcd_init_cb(void); +bool usbtmcd_deinit(void); uint16_t usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); void usbtmcd_reset_cb(uint8_t rhport); bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); 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 diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index a68cb2156..e87ce3997 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -169,23 +169,49 @@ uint32_t tud_vendor_n_write_available (uint8_t itf) //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ -void vendord_init(void) -{ +void vendord_init(void) { tu_memclr(_vendord_itf, sizeof(_vendord_itf)); - 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)); - tu_fifo_config_mutex(&p_itf->tx_ff, osal_mutex_create(&p_itf->tx_ff_mutex), NULL); + #if OSAL_MUTEX_REQUIRED + osal_mutex_t mutex_rd = osal_mutex_create(&p_itf->rx_ff_mutex); + osal_mutex_t mutex_wr = osal_mutex_create(&p_itf->tx_ff_mutex); + TU_ASSERT(mutex_rd && mutex_wr,); + + tu_fifo_config_mutex(&p_itf->rx_ff, NULL, mutex_rd); + tu_fifo_config_mutex(&p_itf->tx_ff, mutex_wr, NULL); + #endif } } +bool vendord_deinit(void) { + #if OSAL_MUTEX_REQUIRED + for(uint8_t i=0; irx_ff.mutex_rd; + osal_mutex_t mutex_wr = p_itf->tx_ff.mutex_wr; + + if (mutex_rd) { + osal_mutex_delete(mutex_rd); + tu_fifo_config_mutex(&p_itf->rx_ff, NULL, NULL); + } + + if (mutex_wr) { + osal_mutex_delete(mutex_wr); + tu_fifo_config_mutex(&p_itf->tx_ff, NULL, NULL); + } + } + #endif + + return true; +} + void vendord_reset(uint8_t rhport) { (void) rhport; diff --git a/src/class/vendor/vendor_device.h b/src/class/vendor/vendor_device.h index d239406b4..cd69ec7c6 100644 --- a/src/class/vendor/vendor_device.h +++ b/src/class/vendor/vendor_device.h @@ -139,6 +139,7 @@ static inline uint32_t tud_vendor_write_available (void) // Internal Class Driver API //--------------------------------------------------------------------+ void vendord_init(void); +bool vendord_deinit(void); void vendord_reset(uint8_t rhport); uint16_t vendord_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index 5306356ba..c30690232 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -1229,6 +1229,10 @@ void videod_init(void) { } } +bool videod_deinit(void) { + return true; +} + void videod_reset(uint8_t rhport) { (void) rhport; for (uint_fast8_t i = 0; i < CFG_TUD_VIDEO; ++i) { diff --git a/src/class/video/video_device.h b/src/class/video/video_device.h index ee2fcb9d5..92930c013 100644 --- a/src/class/video/video_device.h +++ b/src/class/video/video_device.h @@ -85,6 +85,7 @@ TU_ATTR_WEAK int tud_video_commit_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, // INTERNAL USBD-CLASS DRIVER API //--------------------------------------------------------------------+ void videod_init (void); +bool videod_deinit (void); void videod_reset (uint8_t rhport); uint16_t videod_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool videod_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); diff --git a/src/device/dcd.h b/src/device/dcd.h index 21f404e4f..d4f105aa3 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -123,7 +123,7 @@ void dcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) TU_ATTR_W void dcd_init(uint8_t rhport); // Deinitialize controller, unset device mode. -void dcd_deinit(uint8_t rhport); +bool dcd_deinit(uint8_t rhport); // Interrupt Handler void dcd_int_handler(uint8_t rhport); diff --git a/src/device/usbd.c b/src/device/usbd.c index 8f98862c6..439e071ff 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -43,8 +43,13 @@ #endif //--------------------------------------------------------------------+ -// Callback weak stubs (called if application does not provide) +// 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; @@ -85,17 +90,18 @@ 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, .open = cdcd_open, .control_xfer_cb = cdcd_control_xfer_cb, @@ -106,8 +112,9 @@ 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, .open = mscd_open, .control_xfer_cb = mscd_control_xfer_cb, @@ -118,121 +125,131 @@ tu_static usbd_class_driver_t const _usbd_driver[] = { #if CFG_TUD_HID { - DRIVER_NAME("HID") - .init = hidd_init, - .reset = hidd_reset, - .open = hidd_open, - .control_xfer_cb = hidd_control_xfer_cb, - .xfer_cb = hidd_xfer_cb, - .sof = NULL + .name = DRIVER_NAME("HID"), + .init = hidd_init, + .deinit = hidd_deinit, + .reset = hidd_reset, + .open = hidd_open, + .control_xfer_cb = hidd_control_xfer_cb, + .xfer_cb = hidd_xfer_cb, + .sof = NULL }, #endif #if CFG_TUD_AUDIO { - DRIVER_NAME("AUDIO") - .init = audiod_init, - .reset = audiod_reset, - .open = audiod_open, - .control_xfer_cb = audiod_control_xfer_cb, - .xfer_cb = audiod_xfer_cb, - .sof = audiod_sof_isr + .name = DRIVER_NAME("AUDIO"), + .init = audiod_init, + .deinit = audiod_deinit, + .reset = audiod_reset, + .open = audiod_open, + .control_xfer_cb = audiod_control_xfer_cb, + .xfer_cb = audiod_xfer_cb, + .sof = audiod_sof_isr }, #endif #if CFG_TUD_VIDEO { - DRIVER_NAME("VIDEO") - .init = videod_init, - .reset = videod_reset, - .open = videod_open, - .control_xfer_cb = videod_control_xfer_cb, - .xfer_cb = videod_xfer_cb, - .sof = NULL + .name = DRIVER_NAME("VIDEO"), + .init = videod_init, + .deinit = videod_deinit, + .reset = videod_reset, + .open = videod_open, + .control_xfer_cb = videod_control_xfer_cb, + .xfer_cb = videod_xfer_cb, + .sof = NULL }, #endif #if CFG_TUD_MIDI { - DRIVER_NAME("MIDI") - .init = midid_init, - .open = midid_open, - .reset = midid_reset, - .control_xfer_cb = midid_control_xfer_cb, - .xfer_cb = midid_xfer_cb, - .sof = NULL + .name = DRIVER_NAME("MIDI"), + .init = midid_init, + .deinit = midid_deinit, + .open = midid_open, + .reset = midid_reset, + .control_xfer_cb = midid_control_xfer_cb, + .xfer_cb = midid_xfer_cb, + .sof = NULL }, #endif #if CFG_TUD_VENDOR { - DRIVER_NAME("VENDOR") - .init = vendord_init, - .reset = vendord_reset, - .open = vendord_open, - .control_xfer_cb = tud_vendor_control_xfer_cb, - .xfer_cb = vendord_xfer_cb, - .sof = NULL + .name = DRIVER_NAME("VENDOR"), + .init = vendord_init, + .deinit = vendord_deinit, + .reset = vendord_reset, + .open = vendord_open, + .control_xfer_cb = tud_vendor_control_xfer_cb, + .xfer_cb = vendord_xfer_cb, + .sof = NULL }, #endif #if CFG_TUD_USBTMC { - DRIVER_NAME("TMC") - .init = usbtmcd_init_cb, - .reset = usbtmcd_reset_cb, - .open = usbtmcd_open_cb, - .control_xfer_cb = usbtmcd_control_xfer_cb, - .xfer_cb = usbtmcd_xfer_cb, - .sof = NULL + .name = DRIVER_NAME("TMC"), + .init = usbtmcd_init_cb, + .deinit = usbtmcd_deinit, + .reset = usbtmcd_reset_cb, + .open = usbtmcd_open_cb, + .control_xfer_cb = usbtmcd_control_xfer_cb, + .xfer_cb = usbtmcd_xfer_cb, + .sof = NULL }, #endif #if CFG_TUD_DFU_RUNTIME { - DRIVER_NAME("DFU-RUNTIME") - .init = dfu_rtd_init, - .reset = dfu_rtd_reset, - .open = dfu_rtd_open, - .control_xfer_cb = dfu_rtd_control_xfer_cb, - .xfer_cb = NULL, - .sof = NULL + .name = DRIVER_NAME("DFU-RUNTIME"), + .init = dfu_rtd_init, + .deinit = dfu_rtd_deinit, + .reset = dfu_rtd_reset, + .open = dfu_rtd_open, + .control_xfer_cb = dfu_rtd_control_xfer_cb, + .xfer_cb = NULL, + .sof = NULL }, #endif #if CFG_TUD_DFU { - DRIVER_NAME("DFU") - .init = dfu_moded_init, - .reset = dfu_moded_reset, - .open = dfu_moded_open, - .control_xfer_cb = dfu_moded_control_xfer_cb, - .xfer_cb = NULL, - .sof = NULL + .name = DRIVER_NAME("DFU"), + .init = dfu_moded_init, + .deinit = dfu_moded_deinit, + .reset = dfu_moded_reset, + .open = dfu_moded_open, + .control_xfer_cb = dfu_moded_control_xfer_cb, + .xfer_cb = NULL, + .sof = NULL }, #endif #if CFG_TUD_ECM_RNDIS || CFG_TUD_NCM { - DRIVER_NAME("NET") - .init = netd_init, - .reset = netd_reset, - .open = netd_open, - .control_xfer_cb = netd_control_xfer_cb, - .xfer_cb = netd_xfer_cb, - .sof = NULL, + .name = DRIVER_NAME("NET"), + .init = netd_init, + .deinit = netd_deinit, + .reset = netd_reset, + .open = netd_open, + .control_xfer_cb = netd_control_xfer_cb, + .xfer_cb = netd_xfer_cb, + .sof = NULL, }, #endif #if CFG_TUD_BTH { - DRIVER_NAME("BTH") - .init = btd_init, - .reset = btd_reset, - .open = btd_open, - .control_xfer_cb = btd_control_xfer_cb, - .xfer_cb = btd_xfer_cb, - .sof = NULL + .name = DRIVER_NAME("BTH"), + .init = btd_init, + .deinit = btd_deinit, + .reset = btd_reset, + .open = btd_open, + .control_xfer_cb = btd_control_xfer_cb, + .xfer_cb = btd_xfer_cb, + .sof = NULL }, #endif }; @@ -402,7 +419,7 @@ bool tud_init(uint8_t rhport) { // Init class drivers for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { usbd_class_driver_t const* driver = get_driver(i); - TU_ASSERT(driver); + TU_ASSERT(driver && driver->init); TU_LOG_USBD("%s init\r\n", driver->name); driver->init(); } @@ -416,6 +433,41 @@ bool tud_init(uint8_t rhport) { return true; } +bool tud_deinit(uint8_t rhport) { + // skip if not initialized + if (!tud_inited()) return true; + + TU_LOG_USBD("USBD deinit on controller %u\r\n", rhport); + + // Deinit device controller driver + dcd_int_disable(rhport); + dcd_disconnect(rhport); + dcd_deinit(rhport); + + // Deinit class drivers + for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { + usbd_class_driver_t const* driver = get_driver(i); + if(driver && driver->deinit) { + TU_LOG_USBD("%s deinit\r\n", driver->name); + driver->deinit(); + } + } + + // Deinit device queue & task + osal_queue_delete(_usbd_q); + _usbd_q = NULL; + +#if OSAL_MUTEX_REQUIRED + // TODO make sure there is no task waiting on this mutex + osal_mutex_delete(_usbd_mutex); + _usbd_mutex = NULL; +#endif + + _usbd_rhport = RHPORT_INVALID; + + return true; +} + static void configuration_reset(uint8_t rhport) { for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { usbd_class_driver_t const* driver = get_driver(i); diff --git a/src/device/usbd.h b/src/device/usbd.h index a9350192b..0197628e2 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -41,7 +41,7 @@ extern "C" { bool tud_init (uint8_t rhport); // Deinit device stack on roothub port -void tud_deinit(uint8_t rhport); +bool tud_deinit(uint8_t rhport); // Check if device stack is already initialized bool tud_inited(void); diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h index 9039bc9d6..5ae96e589 100644 --- a/src/device/usbd_pvt.h +++ b/src/device/usbd_pvt.h @@ -40,11 +40,9 @@ //--------------------------------------------------------------------+ 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); uint16_t (* open ) (uint8_t rhport, tusb_desc_interface_t const * desc_intf, uint16_t max_len); bool (* control_xfer_cb ) (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); diff --git a/src/host/usbh.c b/src/host/usbh.c index aa0603d47..6a5491998 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -425,7 +425,7 @@ bool tuh_deinit(uint8_t rhport) { // Class drivers for (uint8_t drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) { usbh_class_driver_t const* driver = get_driver(drv_id); - if (driver) { + if (driver && driver->deinit) { TU_LOG_USBH("%s deinit\r\n", driver->name); driver->deinit(); } diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index ccc7ee102..a2b3375a3 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -407,16 +407,17 @@ void dcd_init(uint8_t rhport) { dcd_connect(rhport); } -void dcd_deinit(uint8_t rhport) { +bool dcd_deinit(uint8_t rhport) { assert(rhport == 0); - dcd_disconnect(rhport); reset_non_control_endpoints(); irq_remove_handler(USBCTRL_IRQ, dcd_rp2040_irq); // reset usb hardware into initial state reset_block(RESETS_RESET_USBCTRL_BITS); unreset_block_wait(RESETS_RESET_USBCTRL_BITS); + + return true; } void dcd_int_enable(__unused uint8_t rhport) { diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index 762753a25..222dbbbf0 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -409,12 +409,14 @@ bool hcd_init(uint8_t rhport) return true; } -void hcd_deinit(uint8_t rhport) { +bool hcd_deinit(uint8_t rhport) { (void) rhport; irq_remove_handler(USBCTRL_IRQ, hcd_rp2040_irq); reset_block(RESETS_RESET_USBCTRL_BITS); unreset_block_wait(RESETS_RESET_USBCTRL_BITS); + + return true; } void hcd_port_reset(uint8_t rhport) diff --git a/src/tusb_option.h b/src/tusb_option.h index 2921d3ae0..cbcb69edd 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -34,7 +34,7 @@ #define TUSB_VERSION_MAJOR 0 #define TUSB_VERSION_MINOR 16 #define TUSB_VERSION_REVISION 0 -#define TUSB_VERSION_BUILD 2 +#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_STRING TU_STRING(TUSB_VERSION_MAJOR) "." TU_STRING(TUSB_VERSION_MINOR) "." TU_STRING(TUSB_VERSION_REVISION) From 366564e952b974a49a5b8da7f1d4c729bd37219d Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 8 Apr 2024 22:13:05 +0700 Subject: [PATCH 248/454] fix missing if mutex required --- src/class/usbtmc/usbtmc_device.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 972a450e6..286cbe108 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -261,7 +261,9 @@ void usbtmcd_init_cb(void) } bool usbtmcd_deinit(void) { + #if OSAL_MUTEX_REQUIRED osal_mutex_delete(usbtmcLock); + #endif return true; } From 4bc6a5feb74e073824cf404916442311b7040c47 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 8 Apr 2024 22:22:00 +0700 Subject: [PATCH 249/454] fix unused warning --- src/portable/raspberrypi/rp2040/dcd_rp2040.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index a2b3375a3..bc0deee32 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -408,7 +408,7 @@ void dcd_init(uint8_t rhport) { } bool dcd_deinit(uint8_t rhport) { - assert(rhport == 0); + (void) rhport; reset_non_control_endpoints(); irq_remove_handler(USBCTRL_IRQ, dcd_rp2040_irq); From be25a3fc20339c27803e68cb1363f89ffe7a7c67 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 8 Apr 2024 22:56:22 +0700 Subject: [PATCH 250/454] revert usbd driver name change to be backward compatible --- src/device/usbd.c | 28 ++++++++++++++-------------- src/device/usbd_pvt.h | 3 +++ 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index 439e071ff..96982c30b 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 + #define DRIVER_NAME(_name) .name = _name, #else - #define DRIVER_NAME(_name) NULL + #define DRIVER_NAME(_name) #endif // Built-in class drivers tu_static usbd_class_driver_t const _usbd_driver[] = { #if CFG_TUD_CDC { - .name = DRIVER_NAME("CDC"), + 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 { - .name = DRIVER_NAME("MSC"), + 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 { - .name = DRIVER_NAME("HID"), + 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 { - .name = DRIVER_NAME("AUDIO"), + 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 { - .name = DRIVER_NAME("VIDEO"), + 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 { - .name = DRIVER_NAME("MIDI"), + 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 { - .name = DRIVER_NAME("VENDOR"), + 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 { - .name = DRIVER_NAME("TMC"), + 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 { - .name = DRIVER_NAME("DFU-RUNTIME"), + 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 { - .name = DRIVER_NAME("DFU"), + 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 { - .name = DRIVER_NAME("NET"), + 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 { - .name = DRIVER_NAME("BTH"), + 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 5ae96e589..47752f32c 100644 --- a/src/device/usbd_pvt.h +++ b/src/device/usbd_pvt.h @@ -40,7 +40,10 @@ //--------------------------------------------------------------------+ 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); From 5c7876d4444de25942778728d377ec77f74a75dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Sch=C3=A4r?= Date: Thu, 28 Jul 2022 13:01:36 +0200 Subject: [PATCH 251/454] Fixed behavior of the PRCR register. Previous write protection will be recovered. --- .idea/cmake.xml | 2 +- examples/device/cdc_msc_freertos/src/freertos_hook.c | 3 ++- examples/device/hid_composite_freertos/src/freertos_hook.c | 3 ++- src/common/tusb_compiler.h | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.idea/cmake.xml b/.idea/cmake.xml index ebc6a0570..e4a08eaa6 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -75,7 +75,7 @@ - + diff --git a/examples/device/cdc_msc_freertos/src/freertos_hook.c b/examples/device/cdc_msc_freertos/src/freertos_hook.c index ab885947c..3cd27e08c 100644 --- a/examples/device/cdc_msc_freertos/src/freertos_hook.c +++ b/examples/device/cdc_msc_freertos/src/freertos_hook.c @@ -99,9 +99,10 @@ void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, Stack 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); + SYSTEM.PRCR.WORD = oldPRCR; CMT0.CMCNT = 0; CMT0.CMCOR = (unsigned short)(((configPERIPHERAL_CLOCK_HZ/configTICK_RATE_HZ)-1)/128); diff --git a/examples/device/hid_composite_freertos/src/freertos_hook.c b/examples/device/hid_composite_freertos/src/freertos_hook.c index ab885947c..3cd27e08c 100644 --- a/examples/device/hid_composite_freertos/src/freertos_hook.c +++ b/examples/device/hid_composite_freertos/src/freertos_hook.c @@ -99,9 +99,10 @@ void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, Stack 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); + SYSTEM.PRCR.WORD = oldPRCR; CMT0.CMCNT = 0; CMT0.CMCOR = (unsigned short)(((configPERIPHERAL_CLOCK_HZ/configTICK_RATE_HZ)-1)/128); diff --git a/src/common/tusb_compiler.h b/src/common/tusb_compiler.h index 6f07bdd53..86d150c68 100644 --- a/src/common/tusb_compiler.h +++ b/src/common/tusb_compiler.h @@ -56,7 +56,7 @@ #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L #define TU_VERIFY_STATIC _Static_assert #elif defined(__CCRX__) - #define TU_VERIFY_STATIC(const_expr, _mess) typedef char TU_XSTRCAT(Line, __LINE__)[(const_expr) ? 1 : 0]; + #define TU_VERIFY_STATIC(const_expr, _mess) typedef char TU_XSTRCAT3(Line, __LINE__, _TU_COUNTER_)[(const_expr) ? 1 : 0]; #else #define TU_VERIFY_STATIC(const_expr, _mess) enum { TU_XSTRCAT(_verify_static_, _TU_COUNTER_) = 1/(!!(const_expr)) } #endif From 385611c5a9157569205986550022dee090f26c2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Sch=C3=A4r?= Date: Thu, 28 Jul 2022 13:11:15 +0200 Subject: [PATCH 252/454] Revert "Fixed behavior of the PRCR register. Previous write protection will be recovered." This reverts commit 4d7296109e31690972d8cf09e6138131938cb0ed. --- examples/device/cdc_msc_freertos/src/freertos_hook.c | 3 +-- examples/device/hid_composite_freertos/src/freertos_hook.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/examples/device/cdc_msc_freertos/src/freertos_hook.c b/examples/device/cdc_msc_freertos/src/freertos_hook.c index 3cd27e08c..ab885947c 100644 --- a/examples/device/cdc_msc_freertos/src/freertos_hook.c +++ b/examples/device/cdc_msc_freertos/src/freertos_hook.c @@ -99,10 +99,9 @@ void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, Stack 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 = oldPRCR; + SYSTEM.PRCR.WORD = (0xA5u<<8); CMT0.CMCNT = 0; CMT0.CMCOR = (unsigned short)(((configPERIPHERAL_CLOCK_HZ/configTICK_RATE_HZ)-1)/128); diff --git a/examples/device/hid_composite_freertos/src/freertos_hook.c b/examples/device/hid_composite_freertos/src/freertos_hook.c index 3cd27e08c..ab885947c 100644 --- a/examples/device/hid_composite_freertos/src/freertos_hook.c +++ b/examples/device/hid_composite_freertos/src/freertos_hook.c @@ -99,10 +99,9 @@ void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, Stack 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 = oldPRCR; + SYSTEM.PRCR.WORD = (0xA5u<<8); CMT0.CMCNT = 0; CMT0.CMCOR = (unsigned short)(((configPERIPHERAL_CLOCK_HZ/configTICK_RATE_HZ)-1)/128); From bd67fdf01108304061f9dfaf4aa8624bb2a731ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Sch=C3=A4r?= Date: Thu, 28 Jul 2022 13:25:39 +0200 Subject: [PATCH 253/454] Renesas RX controllers: Recover the previous state of the system write protect register in functions that are called within init-code --- examples/device/cdc_msc_freertos/src/freertos_hook.c | 3 ++- examples/device/hid_composite_freertos/src/freertos_hook.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/device/cdc_msc_freertos/src/freertos_hook.c b/examples/device/cdc_msc_freertos/src/freertos_hook.c index ab885947c..4920e3fae 100644 --- a/examples/device/cdc_msc_freertos/src/freertos_hook.c +++ b/examples/device/cdc_msc_freertos/src/freertos_hook.c @@ -99,9 +99,10 @@ void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, Stack 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); + SYSTEM.PRCR.WORD = (0xA5u<<8) | oldPRCR; CMT0.CMCNT = 0; CMT0.CMCOR = (unsigned short)(((configPERIPHERAL_CLOCK_HZ/configTICK_RATE_HZ)-1)/128); diff --git a/examples/device/hid_composite_freertos/src/freertos_hook.c b/examples/device/hid_composite_freertos/src/freertos_hook.c index ab885947c..4920e3fae 100644 --- a/examples/device/hid_composite_freertos/src/freertos_hook.c +++ b/examples/device/hid_composite_freertos/src/freertos_hook.c @@ -99,9 +99,10 @@ void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, Stack 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); + SYSTEM.PRCR.WORD = (0xA5u<<8) | oldPRCR; CMT0.CMCNT = 0; CMT0.CMCOR = (unsigned short)(((configPERIPHERAL_CLOCK_HZ/configTICK_RATE_HZ)-1)/128); From b0568e32a5d3ad427d296e0d3bcb1020d54d25a3 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Tue, 9 Apr 2024 10:47:06 +0200 Subject: [PATCH 254/454] Fix tud_video_n_streaming check --- src/class/video/video_device.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index d0a88eb17..4218835aa 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -763,8 +763,8 @@ static bool _open_vs_itf(uint8_t rhport, videod_streaming_interface_t *stm, uint tusb_desc_endpoint_t const *ep = (tusb_desc_endpoint_t const*)(desc + ofs_ep); /* Only ISO endpoints needs to be closed */ if(ep->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) { - usbd_edpt_close(rhport, ep->bEndpointAddress); stm->desc.ep[i] = 0; + usbd_edpt_close(rhport, ep->bEndpointAddress); TU_LOG_DRV(" close EP%02x\r\n", ep->bEndpointAddress); } } @@ -1186,6 +1186,16 @@ bool tud_video_n_streaming(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) videod_streaming_interface_t *stm = _get_instance_streaming(ctl_idx, stm_idx); if (!stm || !stm->desc.ep[0]) return false; if (stm->state == VS_STATE_PROBING) return false; + +#ifdef TUP_DCD_EDPT_ISO_ALLOC + uint8_t const *desc = _videod_itf[stm->index_vc].beg; + uint_fast16_t ofs_ep = stm->desc.ep[0]; + tusb_desc_endpoint_t const *ep = (tusb_desc_endpoint_t const*)(desc + ofs_ep); + if (ep->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) { + if (stm->state == VS_STATE_COMMITTED) return false; + } +#endif + return true; } From 2828a56a4f858c6ad72fec3175fec5ff794e2fac Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 9 Apr 2024 17:05:25 +0700 Subject: [PATCH 255/454] apply oldPRCR to board_init() --- .idea/cmake.xml | 2 +- examples/build_system/make/rules.mk | 26 ++++++++++---------- hw/bsp/rx/boards/rx65n_target/rx65n_target.c | 4 ++- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/.idea/cmake.xml b/.idea/cmake.xml index e4a08eaa6..ebc6a0570 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -75,7 +75,7 @@ - + diff --git a/examples/build_system/make/rules.mk b/examples/build_system/make/rules.mk index b02665cdd..78fce49d2 100644 --- a/examples/build_system/make/rules.mk +++ b/examples/build_system/make/rules.mk @@ -9,19 +9,6 @@ # ESP32-Sx and RP2040 has its own CMake build system ifeq (,$(findstring $(FAMILY),espressif rp2040)) -# --------------------------------------- -# Compiler Flags -# --------------------------------------- - -CFLAGS += $(addprefix -I,$(INC)) - -# Verbose mode -ifeq ("$(V)","1") -$(info CFLAGS $(CFLAGS) ) $(info ) -$(info LDFLAGS $(LDFLAGS)) $(info ) -$(info ASFLAGS $(ASFLAGS)) $(info ) -endif - # --------------------------------------- # Rules # --------------------------------------- @@ -39,6 +26,19 @@ vpath %.S . $(TOP) include ${TOP}/examples/build_system/make/toolchain/arm_$(TOOLCHAIN)_rules.mk +# --------------------------------------- +# Compiler Flags +# --------------------------------------- + +CFLAGS += $(addprefix -I,$(INC)) + +# Verbose mode +ifeq ("$(V)","1") +$(info CFLAGS $(CFLAGS) ) $(info ) +$(info LDFLAGS $(LDFLAGS)) $(info ) +$(info ASFLAGS $(ASFLAGS)) $(info ) +endif + OBJ_DIRS = $(sort $(dir $(OBJ))) $(OBJ): | $(OBJ_DIRS) diff --git a/hw/bsp/rx/boards/rx65n_target/rx65n_target.c b/hw/bsp/rx/boards/rx65n_target/rx65n_target.c index 032dac810..66a319541 100644 --- a/hw/bsp/rx/boards/rx65n_target/rx65n_target.c +++ b/hw/bsp/rx/boards/rx65n_target/rx65n_target.c @@ -249,9 +249,10 @@ void board_init(void) EN(SCI5, TEI5) = 1; /* Enable USB0 */ + unsigned short oldPRCR = SYSTEM.PRCR.WORD; SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY | SYSTEM_PRCR_PRC1; MSTP(USB0) = 0; - SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY; + SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY | oldPRCR; /* setup USBI0 interrupt. */ IR(USB0, USBI0) = 0; @@ -277,6 +278,7 @@ int board_uart_read(uint8_t* buf, int len) sci_buf[1].buf = buf; sci_buf[1].cnt = len; SCI5.SCR.BYTE |= SCI_SCR_RE | SCI_SCR_RIE; + // TODO change to non blocking, return -1 immediately if no data while (SCI5.SCR.BIT.RE) ; return len - sci_buf[1].cnt; } From 27fc8a21cd06b20a60c947de795bf135f98c9610 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 9 Apr 2024 17:07:59 +0700 Subject: [PATCH 256/454] update gr_citrus as well --- hw/bsp/rx/boards/gr_citrus/gr_citrus.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hw/bsp/rx/boards/gr_citrus/gr_citrus.c b/hw/bsp/rx/boards/gr_citrus/gr_citrus.c index 5078c7569..26ad4a6aa 100644 --- a/hw/bsp/rx/boards/gr_citrus/gr_citrus.c +++ b/hw/bsp/rx/boards/gr_citrus/gr_citrus.c @@ -203,9 +203,10 @@ void board_init(void) IEN(SCI0, TEI0) = 1; /* Enable USB0 */ + unsigned short oldPRCR = SYSTEM.PRCR.WORD; SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY | SYSTEM_PRCR_PRC1; MSTP(USB0) = 0; - SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY; + SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY | oldPRCR; } //--------------------------------------------------------------------+ From 6c2f71ad19bbe9e3d346b5631ede9557b4252088 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 9 Apr 2024 17:12:15 +0700 Subject: [PATCH 257/454] make veryfi static in ccrx consistent with the rest --- src/common/tusb_compiler.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/tusb_compiler.h b/src/common/tusb_compiler.h index 86d150c68..0d5570b1c 100644 --- a/src/common/tusb_compiler.h +++ b/src/common/tusb_compiler.h @@ -56,7 +56,7 @@ #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L #define TU_VERIFY_STATIC _Static_assert #elif defined(__CCRX__) - #define TU_VERIFY_STATIC(const_expr, _mess) typedef char TU_XSTRCAT3(Line, __LINE__, _TU_COUNTER_)[(const_expr) ? 1 : 0]; + #define TU_VERIFY_STATIC(const_expr, _mess) typedef char TU_XSTRCAT(_verify_static_, _TU_COUNTER_)[(const_expr) ? 1 : 0]; #else #define TU_VERIFY_STATIC(const_expr, _mess) enum { TU_XSTRCAT(_verify_static_, _TU_COUNTER_) = 1/(!!(const_expr)) } #endif From ec1a06843c15bdbc249002d7914ff3d663e25f2c Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 9 Apr 2024 17:37:12 +0700 Subject: [PATCH 258/454] more try/catch for labeler --- .github/workflows/labeler.yml | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index 947b08ca2..51ff1cfed 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -28,8 +28,8 @@ jobs: issueOrPrNumber = context.payload.pull_request.number; } + // Check if an Adafruit member try { - // Check for Adafruit membership const adafruitResponse = await github.rest.orgs.checkMembershipForUser({ org: 'adafruit', username: username @@ -38,8 +38,14 @@ jobs: if (adafruitResponse.status === 204) { console.log('Adafruit Member'); label = 'Prio Urgent'; - } else { - // If not a Adafruit member, check if the user is a contributor + } + } catch (error) { + console.log('Not an Adafruit member'); + } + + // Check if a contributor + if (label == '') { + try { const collaboratorResponse = await github.rest.repos.checkCollaborator({ owner: context.repo.owner, repo: context.repo.repo, @@ -50,9 +56,9 @@ jobs: console.log('Contributor'); label = 'Prio Higher'; } + } catch (error) { + console.log('Not a contributor'); } - } catch (error) { - console.log(`Error processing user ${username}: ${error.message}`); } if (label !== '') { From 455a2879fbb293b85c4e8d9ec3d4f172cf77803e Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Tue, 9 Apr 2024 12:34:36 +0200 Subject: [PATCH 259/454] Fix typo. --- examples/device/video_capture_2ch/src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/device/video_capture_2ch/src/main.c b/examples/device/video_capture_2ch/src/main.c index 82bc7d6ca..eb1cf2580 100644 --- a/examples/device/video_capture_2ch/src/main.c +++ b/examples/device/video_capture_2ch/src/main.c @@ -184,7 +184,7 @@ size_t get_framebuf(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, size_t fnum, voi if (idx == 0) { // stream 0 use uncompressed YUY2 frame #if defined(CFG_EXAMPLE_VIDEO_READONLY) - *fb = (void*)(uintptr_t ) framebuf_yuy2_readonly[(fnum % (FRAME_WIDTH / 2)) * 4]; + *fb = (void*)(uintptr_t ) &framebuf_yuy2_readonly[(fnum % (FRAME_WIDTH / 2)) * 4]; #else fill_color_bar(framebuf_yuy2, frame_num[idx]); *fb = framebuf_yuy2; From bf240ce9bbdd9ce06422d1136b9b6799fa700ba3 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 9 Apr 2024 19:50:10 +0700 Subject: [PATCH 260/454] add permission to lable issue/pr --- .github/workflows/labeler.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index 51ff1cfed..5b22d977e 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -9,7 +9,9 @@ on: jobs: label-priority: runs-on: ubuntu-latest - + permissions: + issues: write + pull-requests: write steps: - name: Label New Issue or PR uses: actions/github-script@v7 From 00db4227451b223c939f7a84e93199a73519d04a Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 5 Apr 2024 13:12:24 +0200 Subject: [PATCH 261/454] Cleanup ep/pma free, ISO ep should use alloc/activate. --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 99 ++----------------- 1 file changed, 8 insertions(+), 91 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 7bf726f3f..41b5acbc6 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -183,12 +183,9 @@ static void dcd_transmit_packet(xfer_ctl_t * xfer, uint16_t ep_ix); static void dcd_ep_ctr_handler(void); // PMA allocation/access -static uint8_t open_ep_count; static uint16_t ep_buf_ptr; ///< Points to first free memory location static void dcd_pma_alloc_reset(void); static uint16_t dcd_pma_alloc(uint8_t ep_addr, uint16_t length); -static void dcd_pma_free(uint8_t ep_addr); -static void dcd_ep_free(uint8_t ep_addr); 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); @@ -765,7 +762,6 @@ void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * re static void dcd_pma_alloc_reset(void) { - open_ep_count = 0; ep_buf_ptr = DCD_STM32_BTABLE_BASE + 8*MAX_EP_COUNT; // 8 bytes per endpoint (two TX and two RX words, each) //TU_LOG2("dcd_pma_alloc_reset()\r\n"); for(uint32_t i=0; i 2, /**/); - TU_ASSERT(xfer_ctl_ptr(ep_addr)->max_packet_size != 0, /**/); - open_ep_count--; - - // If count is 2, only EP0 should be open, so allocations can be mostly reset. - - if(open_ep_count == 2) - { - ep_buf_ptr = DCD_STM32_BTABLE_BASE + 8*MAX_EP_COUNT + 2*CFG_TUD_ENDPOINT0_SIZE; // 8 bytes per endpoint (two TX and two RX words, each), and EP0 - - // Skip EP0 - for(uint32_t i=1; ipma_alloc_size = 0U; - xfer_ctl_ptr(tu_edpt_addr(i,TUSB_DIR_IN))->pma_alloc_size = 0U; - xfer_ctl_ptr(tu_edpt_addr(i,TUSB_DIR_OUT))->pma_ptr = 0U; - xfer_ctl_ptr(tu_edpt_addr(i,TUSB_DIR_IN))->pma_ptr = 0U; - } - } -} - /*** * Allocate hardware endpoint */ @@ -892,34 +859,6 @@ static uint8_t dcd_ep_alloc(uint8_t ep_addr, uint8_t ep_type) TU_ASSERT(0); } -/*** - * Free hardware endpoint - */ -static void dcd_ep_free(uint8_t ep_addr) -{ - 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++) - { - // Check if EP number & dir are the same - if(ep_alloc_status[i].ep_num == epnum && - ep_alloc_status[i].allocated[dir] == dir) - { - ep_alloc_status[i].allocated[dir] = false; - // Reset entry if ISO endpoint or both direction are free - if(ep_alloc_status[i].ep_type == TUSB_XFER_ISOCHRONOUS || - !ep_alloc_status[i].allocated[dir ^ 1]) - { - ep_alloc_status[i].ep_num = 0xFF; - ep_alloc_status[i].ep_type = 0xFF; - - return; - } - } - } -} - // The STM32F0 doesn't seem to like |= or &= to manipulate the EP#R registers, // so I'm using the #define from HAL here, instead. @@ -934,16 +873,16 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc uint32_t wType; TU_ASSERT(ep_idx < STFSDEV_EP_COUNT); - TU_ASSERT(buffer_size <= 1024); + TU_ASSERT(buffer_size <= 64); + + // ISO endpoint should use alloc / active functions + TU_ASSERT(p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS); // Set type switch(p_endpoint_desc->bmAttributes.xfer) { case TUSB_XFER_CONTROL: wType = USB_EP_CONTROL; break; - case TUSB_XFER_ISOCHRONOUS: - wType = USB_EP_ISOCHRONOUS; - break; case TUSB_XFER_BULK: wType = USB_EP_CONTROL; break; @@ -958,45 +897,27 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc pcd_set_eptype(USB, ep_idx, wType); pcd_set_ep_address(USB, ep_idx, tu_edpt_number(p_endpoint_desc->bEndpointAddress)); - // Be normal, for now, instead of only accepting zero-byte packets (on control endpoint) - // or being double-buffered (bulk endpoints) - pcd_clear_ep_kind(USB,0); /* Create a packet memory buffer area. For isochronous endpoints, * use the same buffer as the double buffer, essentially disabling double buffering */ pma_addr = dcd_pma_alloc(p_endpoint_desc->bEndpointAddress, buffer_size); - if( (dir == TUSB_DIR_IN) || (wType == USB_EP_ISOCHRONOUS) ) + if(dir == TUSB_DIR_IN) { pcd_set_ep_tx_address(USB, ep_idx, pma_addr); pcd_set_ep_tx_bufsize(USB, ep_idx, buffer_size); + pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_NAK); pcd_clear_tx_dtog(USB, ep_idx); } - if( (dir == TUSB_DIR_OUT) || (wType == USB_EP_ISOCHRONOUS) ) + if(dir == TUSB_DIR_OUT) { pcd_set_ep_rx_address(USB, ep_idx, pma_addr); pcd_set_ep_rx_bufsize(USB, ep_idx, buffer_size); + pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_NAK); pcd_clear_rx_dtog(USB, ep_idx); } - /* Enable endpoint */ - if (dir == TUSB_DIR_IN) - { - if(wType == USB_EP_ISOCHRONOUS) { - pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_DIS); - } else { - pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_NAK); - } - } else - { - if(wType == USB_EP_ISOCHRONOUS) { - pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_DIS); - } else { - pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_NAK); - } - } - xfer_ctl_ptr(p_endpoint_desc->bEndpointAddress)->max_packet_size = packet_size; xfer_ctl_ptr(p_endpoint_desc->bEndpointAddress)->ep_idx = ep_idx; @@ -1032,10 +953,6 @@ void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) { pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_DIS); } - - dcd_ep_free(ep_addr); - - dcd_pma_free(ep_addr); } bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) From 68b973aa9f64ad03210e5fb669f997a12965525f Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 5 Apr 2024 15:20:13 +0200 Subject: [PATCH 262/454] Reduce uac2_headset max sample rate for better compatibility. --- examples/device/uac2_headset/src/main.c | 6 +----- examples/device/uac2_headset/src/tusb_config.h | 8 +++----- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/examples/device/uac2_headset/src/main.c b/examples/device/uac2_headset/src/main.c index 35b7ac94b..fbd7ffe22 100644 --- a/examples/device/uac2_headset/src/main.c +++ b/examples/device/uac2_headset/src/main.c @@ -35,11 +35,7 @@ //--------------------------------------------------------------------+ // 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 +const uint32_t sample_rates[] = {44100, 48000}; uint32_t current_sample_rate = 44100; diff --git a/examples/device/uac2_headset/src/tusb_config.h b/examples/device/uac2_headset/src/tusb_config.h index 4b08fa676..328e35f52 100644 --- a/examples/device/uac2_headset/src/tusb_config.h +++ b/examples/device/uac2_headset/src/tusb_config.h @@ -114,11 +114,9 @@ extern "C" { #define CFG_TUD_AUDIO_FUNC_1_N_FORMATS 2 // Audio format type I specifications -#if defined(__RX__) -#define CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE 48000 // 16bit/48kHz is the best quality for Renesas RX -#else -#define CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE 96000 // 24bit/96kHz is the best quality for full-speed, high-speed is needed beyond this -#endif +/* 24bit/48kHz is the best quality for headset or 24bit/96kHz for 2ch speaker, + high-speed is needed beyond this */ +#define CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE 48000 #define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 1 #define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX 2 From bf3e9b865302c90bc175e2ed28d64de9dc7bf8c9 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Tue, 9 Apr 2024 13:31:23 +0200 Subject: [PATCH 263/454] Refactor edpt_xfer(), support double buffering in dcd_pma_alloc(). --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 114 ++++++------------ 1 file changed, 37 insertions(+), 77 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 41b5acbc6..f380355ae 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -151,9 +151,7 @@ typedef struct tu_fifo_t * ff; uint16_t total_len; uint16_t queued_len; - uint16_t pma_ptr; uint16_t max_packet_size; - uint16_t pma_alloc_size; uint8_t ep_idx; // index for USB_EPnR register } xfer_ctl_t; @@ -180,12 +178,12 @@ static uint8_t remoteWakeCountdown; // When wake is requested // into the stack. static void dcd_handle_bus_reset(void); 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 -static void dcd_pma_alloc_reset(void); -static uint16_t dcd_pma_alloc(uint8_t ep_addr, uint16_t length); +static uint32_t dcd_pma_alloc(uint8_t ep_addr, uint16_t length, 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); @@ -491,7 +489,9 @@ static void dcd_handle_bus_reset(void) ep_alloc_status[i].allocated[1] = false; } - dcd_pma_alloc_reset(); + // Reset PMA allocation + ep_buf_ptr = DCD_STM32_BTABLE_BASE + 8*MAX_EP_COUNT; + dcd_edpt_open (0, &ep0OUT_desc); dcd_edpt_open (0, &ep0IN_desc); @@ -760,40 +760,15 @@ void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * re } } -static void dcd_pma_alloc_reset(void) -{ - ep_buf_ptr = DCD_STM32_BTABLE_BASE + 8*MAX_EP_COUNT; // 8 bytes per endpoint (two TX and two RX words, each) - //TU_LOG2("dcd_pma_alloc_reset()\r\n"); - for(uint32_t i=0; ipma_alloc_size = 0U; - xfer_ctl_ptr(tu_edpt_addr(i,TUSB_DIR_IN))->pma_alloc_size = 0U; - xfer_ctl_ptr(tu_edpt_addr(i,TUSB_DIR_OUT))->pma_ptr = 0U; - xfer_ctl_ptr(tu_edpt_addr(i,TUSB_DIR_IN))->pma_ptr = 0U; - } -} - /*** * Allocate a section of PMA - * - * If the EP number has already been allocated, and the new allocation - * is larger than the old allocation, then this will fail with a TU_ASSERT. - * (This is done to simplify the code. More complicated algorithms could be used) - * + * 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 uint16_t dcd_pma_alloc(uint8_t ep_addr, uint16_t length) +static uint32_t dcd_pma_alloc(uint8_t ep_addr, uint16_t length, bool dbuf) { xfer_ctl_t* epXferCtl = xfer_ctl_ptr(ep_addr); - if(epXferCtl->pma_alloc_size != 0U) - { - //TU_LOG2("dcd_pma_alloc(%x,%x)=%x (cached)\r\n",ep_addr,length,epXferCtl->pma_ptr); - // Previously allocated - TU_ASSERT(length <= epXferCtl->pma_alloc_size, 0xFFFF); // Verify no larger than previous alloc - return epXferCtl->pma_ptr; - } - // Ensure allocated buffer is aligned #ifdef FSDEV_BUS_32BIT length = (length + 3) & ~0x03; @@ -801,15 +776,16 @@ static uint16_t dcd_pma_alloc(uint8_t ep_addr, uint16_t length) length = (length + 1) & ~0x01; #endif - uint16_t addr = ep_buf_ptr; + uint32_t addr = ep_buf_ptr; ep_buf_ptr = (uint16_t)(ep_buf_ptr + length); // increment buffer pointer - // Verify no overflow - TU_ASSERT(ep_buf_ptr <= FSDEV_PMA_SIZE, 0xFFFF); + if(dbuf) { + addr |= ((uint32_t)ep_buf_ptr) << 16; + ep_buf_ptr = (uint16_t)(ep_buf_ptr + length); // increment buffer pointer + } - epXferCtl->pma_ptr = addr; - epXferCtl->pma_alloc_size = length; - //TU_LOG1("dcd_pma_alloc(%x,%x)=%x\r\n",ep_addr,length,addr); + // Verify packet buffer is not overflowed + TU_ASSERT(ep_buf_ptr <= FSDEV_PMA_SIZE, 0xFFFF); return addr; } @@ -898,9 +874,8 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc pcd_set_eptype(USB, ep_idx, wType); pcd_set_ep_address(USB, ep_idx, tu_edpt_number(p_endpoint_desc->bEndpointAddress)); - /* Create a packet memory buffer area. For isochronous endpoints, - * use the same buffer as the double buffer, essentially disabling double buffering */ - pma_addr = dcd_pma_alloc(p_endpoint_desc->bEndpointAddress, buffer_size); + /* Create a packet memory buffer area. */ + pma_addr = dcd_pma_alloc(p_endpoint_desc->bEndpointAddress, buffer_size, false); if(dir == TUSB_DIR_IN) { @@ -966,7 +941,7 @@ bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet /* Create a packet memory buffer area. For isochronous endpoints, * use the same buffer as the double buffer, essentially disabling double buffering */ - uint16_t pma_addr = dcd_pma_alloc(ep_addr, buffer_size); + uint16_t pma_addr = dcd_pma_alloc(ep_addr, buffer_size, false); xfer_ctl_ptr(ep_addr)->ep_idx = ep_idx; @@ -1036,7 +1011,7 @@ static void dcd_transmit_packet(xfer_ctl_t * xfer, uint16_t ep_ix) xfer->queued_len = (uint16_t)(xfer->queued_len + len); /* Write into correct register when ISOCHRONOUS (double buffered) */ - if ( (ep_reg & USB_EP_DTOG_TX) && ( (ep_reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS) ) { + if ((ep_reg & USB_EP_DTOG_TX) && ((ep_reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS)) { pcd_set_ep_rx_cnt(USB, ep_ix, len); } else { pcd_set_ep_tx_cnt(USB, ep_ix, len); @@ -1045,7 +1020,7 @@ static void dcd_transmit_packet(xfer_ctl_t * xfer, uint16_t ep_ix) pcd_set_ep_tx_status(USB, ep_ix, USB_EP_TX_VALID); } -bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) +static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr) { (void) rhport; @@ -1053,26 +1028,18 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t uint8_t const ep_idx = xfer->ep_idx; uint8_t const dir = tu_edpt_dir(ep_addr); - xfer->buffer = buffer; - xfer->ff = NULL; - xfer->total_len = total_bytes; - xfer->queued_len = 0; - if ( dir == TUSB_DIR_OUT ) { // 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 && buffer == NULL) + if (ep_idx == 0 && xfer->buffer == NULL) { - xfer->buffer = (uint8_t*)_setup_packet; + xfer->buffer = (uint8_t*)_setup_packet; } - if(total_bytes > xfer->max_packet_size) - { - pcd_set_ep_rx_bufsize(USB,ep_idx,xfer->max_packet_size); - } else { - pcd_set_ep_rx_bufsize(USB,ep_idx,total_bytes); - } + uint32_t bufsize = xfer->total_len > xfer->max_packet_size ? xfer->max_packet_size : xfer->total_len; + pcd_set_ep_rx_bufsize(USB, ep_idx, bufsize); + pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_VALID); } else // IN @@ -1082,34 +1049,27 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t return true; } +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; + xfer->queued_len = 0; + + 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) { - (void) rhport; - xfer_ctl_t * xfer = xfer_ctl_ptr(ep_addr); - uint8_t const epnum = xfer->ep_idx; - uint8_t const dir = tu_edpt_dir(ep_addr); - xfer->buffer = NULL; xfer->ff = ff; xfer->total_len = total_bytes; xfer->queued_len = 0; - if ( dir == TUSB_DIR_OUT ) - { - if(total_bytes > xfer->max_packet_size) - { - pcd_set_ep_rx_bufsize(USB,epnum,xfer->max_packet_size); - } else { - pcd_set_ep_rx_bufsize(USB,epnum,total_bytes); - } - pcd_set_ep_rx_status(USB, epnum, USB_EP_RX_VALID); - } - else // IN - { - dcd_transmit_packet(xfer,epnum); - } - return true; + return edpt_xfer(rhport, ep_addr); } void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) From 41fb2b69f72207d069ebbce50a0457c4c5cdfb35 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Tue, 9 Apr 2024 16:20:18 +0200 Subject: [PATCH 264/454] Rework macro according to ST driver. --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h index 946ad2c7c..7992f34a1 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h @@ -298,6 +298,9 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_cnt(USB_TypeDef * USB #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. @@ -331,6 +334,9 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_address(USB_TypeDef * #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; @@ -349,6 +355,9 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_address(USB_TypeDef * USB #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; @@ -359,7 +368,9 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_cnt(USB_TypeDef * USBx, u #endif } -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t 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); @@ -395,14 +406,16 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_bufsize(USB_TypeDef * USBx, pcd_set_ep_blsize_num_blocks(USBx, rxtx_idx, blocksize, numblocks); } -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_bufsize(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { +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_bufsize(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t 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. From 973d29acd095662a3a5f1dfb8d57a3ad8092f89b Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Tue, 9 Apr 2024 16:24:54 +0200 Subject: [PATCH 265/454] Rework ISO double buffering. --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 115 ++++++++++-------- 1 file changed, 62 insertions(+), 53 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index f380355ae..4844c916d 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -586,26 +586,31 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) { } 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) */ - if ( (wEPRegVal & USB_EP_DTOG_RX) && ( (wEPRegVal & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS) ) { - count = pcd_get_ep_tx_cnt(USB, EPindex); + 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); + } } else { count = pcd_get_ep_rx_cnt(USB, EPindex); + addr = pcd_get_ep_rx_address(USB, EPindex); } TU_ASSERT(count <= xfer->max_packet_size, /**/); - // Clear RX CTR interrupt flag - if(ep_addr != 0u) - { - pcd_clear_rx_ep_ctr(USB, EPindex); - } - if (count != 0U) { - uint16_t addr = pcd_get_ep_rx_address(USB, EPindex); - if (xfer->ff) { dcd_read_packet_memory_ff(xfer->ff, addr, count); @@ -627,16 +632,15 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) { } else { - uint32_t remaining = (uint32_t)xfer->total_len - (uint32_t)xfer->queued_len; - if(remaining >= xfer->max_packet_size) { - pcd_set_ep_rx_bufsize(USB, EPindex,xfer->max_packet_size); - } else { - pcd_set_ep_rx_bufsize(USB, EPindex,remaining); - } - + /* Set endpoint active again for receiving more data. + * Note that isochronous endpoints stay active always */ if (!((wEPRegVal & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS)) { - /* Set endpoint active again for receiving more data. - * Note that isochronous endpoints stay active always */ + uint32_t remaining = (uint32_t)xfer->total_len - (uint32_t)xfer->queued_len; + if(remaining >= xfer->max_packet_size) { + pcd_set_ep_rx_cnt(USB, EPindex,xfer->max_packet_size); + } else { + pcd_set_ep_rx_cnt(USB, EPindex,remaining); + } pcd_set_ep_rx_status(USB, EPindex, USB_EP_RX_VALID); } } @@ -648,7 +652,7 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) { if(ep_addr == 0u) { // Always be prepared for a status packet... - pcd_set_ep_rx_bufsize(USB, EPindex, CFG_TUD_ENDPOINT0_SIZE); + pcd_set_ep_rx_cnt(USB, EPindex, CFG_TUD_ENDPOINT0_SIZE); pcd_clear_rx_ep_ctr(USB, EPindex); } } @@ -838,7 +842,7 @@ 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 * p_endpoint_desc) { (void)rhport; uint8_t const ep_idx = dcd_ep_alloc(p_endpoint_desc->bEndpointAddress, p_endpoint_desc->bmAttributes.xfer); @@ -880,7 +884,6 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc if(dir == TUSB_DIR_IN) { pcd_set_ep_tx_address(USB, ep_idx, pma_addr); - pcd_set_ep_tx_bufsize(USB, ep_idx, buffer_size); pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_NAK); pcd_clear_tx_dtog(USB, ep_idx); } @@ -888,7 +891,6 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc if(dir == TUSB_DIR_OUT) { pcd_set_ep_rx_address(USB, ep_idx, pma_addr); - pcd_set_ep_rx_bufsize(USB, ep_idx, buffer_size); pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_NAK); pcd_clear_rx_dtog(USB, ep_idx); } @@ -912,7 +914,7 @@ void dcd_edpt_close_all (uint8_t rhport) * * This also clears transfers in progress, should there be any. */ -void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { (void)rhport; @@ -939,16 +941,15 @@ bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet 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. For isochronous endpoints, - * use the same buffer as the double buffer, essentially disabling double buffering */ - uint16_t pma_addr = dcd_pma_alloc(ep_addr, buffer_size, false); + /* Create a packet memory buffer area. Enable double buffering */ + uint32_t pma_addr = dcd_pma_alloc(ep_addr, buffer_size, true); xfer_ctl_ptr(ep_addr)->ep_idx = ep_idx; pcd_set_eptype(USB, ep_idx, USB_EP_ISOCHRONOUS); - pcd_set_ep_tx_address(USB, ep_idx, pma_addr); - pcd_set_ep_rx_address(USB, ep_idx, pma_addr); + pcd_set_ep_tx_address(USB, ep_idx, pma_addr & 0xFFFF); + pcd_set_ep_rx_address(USB, ep_idx, pma_addr >> 16); return true; } @@ -961,26 +962,20 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpo const uint16_t packet_size = tu_edpt_packet_size(p_endpoint_desc); const uint16_t buffer_size = pcd_aligned_buffer_size(packet_size); - /* Disable endpoint */ - 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); - } + pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_DIS); + pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_DIS); pcd_set_ep_address(USB, ep_idx, tu_edpt_number(p_endpoint_desc->bEndpointAddress)); - // Be normal, for now, instead of only accepting zero-byte packets (on control endpoint) - // or being double-buffered (bulk endpoints) - pcd_clear_ep_kind(USB,0); - pcd_set_ep_tx_bufsize(USB, ep_idx, buffer_size); - pcd_set_ep_rx_bufsize(USB, ep_idx, buffer_size); pcd_clear_tx_dtog(USB, ep_idx); pcd_clear_rx_dtog(USB, ep_idx); + if(dir == TUSB_DIR_IN) { + pcd_rx_dtog(USB, ep_idx); + } else { + pcd_tx_dtog(USB, ep_idx); + } + xfer_ctl_ptr(p_endpoint_desc->bEndpointAddress)->max_packet_size = packet_size; return true; @@ -998,7 +993,21 @@ static void dcd_transmit_packet(xfer_ctl_t * xfer, uint16_t ep_ix) } uint16_t ep_reg = pcd_get_endpoint(USB, ep_ix); - uint16_t addr_ptr = pcd_get_ep_tx_address(USB, ep_ix); + uint16_t addr_ptr; + + + if ((ep_reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS) { + 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); + } + } else { + addr_ptr = pcd_get_ep_tx_address(USB, ep_ix); + pcd_set_ep_tx_cnt(USB, ep_ix, len); + } if (xfer->ff) { @@ -1010,13 +1019,6 @@ static void dcd_transmit_packet(xfer_ctl_t * xfer, uint16_t ep_ix) } xfer->queued_len = (uint16_t)(xfer->queued_len + len); - /* Write into correct register when ISOCHRONOUS (double buffered) */ - if ((ep_reg & USB_EP_DTOG_TX) && ((ep_reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS)) { - pcd_set_ep_rx_cnt(USB, ep_ix, len); - } else { - pcd_set_ep_tx_cnt(USB, ep_ix, len); - } - pcd_set_ep_tx_status(USB, ep_ix, USB_EP_TX_VALID); } @@ -1037,8 +1039,15 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr) xfer->buffer = (uint8_t*)_setup_packet; } - uint32_t bufsize = xfer->total_len > xfer->max_packet_size ? xfer->max_packet_size : xfer->total_len; - pcd_set_ep_rx_bufsize(USB, ep_idx, bufsize); + uint32_t cnt = xfer->total_len > xfer->max_packet_size ? xfer->max_packet_size : xfer->total_len; + 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); + } else { + pcd_set_ep_rx_cnt(USB, ep_idx, cnt); + } pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_VALID); } From 472996e2bfbd14341e99aa58e9f0c24e69a5043e Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Tue, 9 Apr 2024 16:29:08 +0200 Subject: [PATCH 266/454] Ignore spurious RX interrupt. --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 4844c916d..a6d92c7c0 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -153,6 +153,7 @@ typedef struct uint16_t queued_len; uint16_t max_packet_size; uint8_t ep_idx; // index for USB_EPnR register + bool in_complete; // Workaround for ISO IN EP doesn't have interrupt mask } xfer_ctl_t; // EP allocator @@ -518,6 +519,19 @@ static void dcd_ep_ctr_tx_handler(uint32_t wIstr) pcd_clear_tx_ep_ctr(USB, EPindex); xfer_ctl_t * xfer = xfer_ctl_ptr(ep_addr); + + /* Ignore spurious int */ + if(xfer->in_complete) return; + xfer->in_complete = true; + + if ((wEPRegVal & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS) { + 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); + } + } + if((xfer->total_len != xfer->queued_len)) /* TX not complete */ { dcd_transmit_packet(xfer, EPindex); @@ -1019,7 +1033,10 @@ static void dcd_transmit_packet(xfer_ctl_t * xfer, uint16_t ep_ix) } xfer->queued_len = (uint16_t)(xfer->queued_len + len); + dcd_int_disable(0); pcd_set_ep_tx_status(USB, ep_ix, USB_EP_TX_VALID); + xfer->in_complete = false; + dcd_int_enable(0); } static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr) From c0824472e8741ba67b660f34f27b5b4fcfe6c295 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Tue, 9 Apr 2024 22:15:18 +0200 Subject: [PATCH 267/454] Enable double buffer only for PMA > 1024b --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index a6d92c7c0..d85adfe95 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -950,20 +950,26 @@ bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet { (void)rhport; - TU_ASSERT(largest_packet_size <= 1024); + TU_ASSERT(largest_packet_size < 1024); 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 */ + /* Create a packet memory buffer area. Enable double buffering for devices with 2048 bytes PMA, + for smaller devices double buffering occupy too much space. */ +#if FSDEV_PMA_SIZE > 1024u uint32_t pma_addr = dcd_pma_alloc(ep_addr, buffer_size, true); - - xfer_ctl_ptr(ep_addr)->ep_idx = ep_idx; + uint16_t pma_addr2 = pma_addr >> 16; +#else + uint32_t pma_addr = dcd_pma_alloc(ep_addr, 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); pcd_set_eptype(USB, ep_idx, USB_EP_ISOCHRONOUS); - pcd_set_ep_tx_address(USB, ep_idx, pma_addr & 0xFFFF); - pcd_set_ep_rx_address(USB, ep_idx, pma_addr >> 16); + xfer_ctl_ptr(ep_addr)->ep_idx = ep_idx; return true; } From 146c3c69450924d64795bd3d627ad1affaed5af7 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Tue, 9 Apr 2024 22:59:48 +0200 Subject: [PATCH 268/454] Cleanup. --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 26 +++++++------------ 1 file changed, 10 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 d85adfe95..b89961d7d 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -184,7 +184,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(uint8_t ep_addr, uint16_t length, bool dbuf); +static uint32_t dcd_pma_alloc(uint16_t length, 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); @@ -649,14 +649,12 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) { /* Set endpoint active again for receiving more data. * Note that isochronous endpoints stay active always */ if (!((wEPRegVal & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS)) { - uint32_t remaining = (uint32_t)xfer->total_len - (uint32_t)xfer->queued_len; - if(remaining >= xfer->max_packet_size) { - pcd_set_ep_rx_cnt(USB, EPindex,xfer->max_packet_size); - } else { - pcd_set_ep_rx_cnt(USB, EPindex,remaining); - } - pcd_set_ep_rx_status(USB, EPindex, USB_EP_RX_VALID); + uint16_t remaining = xfer->total_len - xfer->queued_len; + uint16_t cnt = remaining >= xfer->max_packet_size ? xfer->max_packet_size : remaining; + pcd_set_ep_rx_cnt(USB, EPindex, cnt); + pcd_set_ep_rx_cnt(USB, EPindex,remaining); } + pcd_set_ep_rx_status(USB, EPindex, USB_EP_RX_VALID); } } @@ -783,10 +781,8 @@ void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * re * 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(uint8_t ep_addr, uint16_t length, bool dbuf) +static uint32_t dcd_pma_alloc(uint16_t length, bool dbuf) { - xfer_ctl_t* epXferCtl = xfer_ctl_ptr(ep_addr); - // Ensure allocated buffer is aligned #ifdef FSDEV_BUS_32BIT length = (length + 3) & ~0x03; @@ -893,7 +889,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) pcd_set_ep_address(USB, ep_idx, tu_edpt_number(p_endpoint_desc->bEndpointAddress)); /* Create a packet memory buffer area. */ - pma_addr = dcd_pma_alloc(p_endpoint_desc->bEndpointAddress, buffer_size, false); + pma_addr = dcd_pma_alloc(buffer_size, false); if(dir == TUSB_DIR_IN) { @@ -958,10 +954,10 @@ 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. */ #if FSDEV_PMA_SIZE > 1024u - uint32_t pma_addr = dcd_pma_alloc(ep_addr, buffer_size, true); + 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(ep_addr, buffer_size, true); + 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); @@ -980,7 +976,6 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpo uint8_t const ep_idx = xfer_ctl_ptr(p_endpoint_desc->bEndpointAddress)->ep_idx; uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); const uint16_t packet_size = tu_edpt_packet_size(p_endpoint_desc); - const uint16_t buffer_size = pcd_aligned_buffer_size(packet_size); pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_DIS); pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_DIS); @@ -1015,7 +1010,6 @@ static void dcd_transmit_packet(xfer_ctl_t * xfer, uint16_t ep_ix) uint16_t ep_reg = pcd_get_endpoint(USB, ep_ix); uint16_t addr_ptr; - if ((ep_reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS) { if (ep_reg & USB_EP_DTOG_TX) { addr_ptr = pcd_get_ep_dbuf1_address(USB, ep_ix); From 402b084646b6d9c7c6520def6de343b7b7fdab07 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Tue, 9 Apr 2024 23:00:29 +0200 Subject: [PATCH 269/454] Format doc. --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 603 ++++++++---------- 1 file changed, 260 insertions(+), 343 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index b89961d7d..c11a8c625 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -107,9 +107,9 @@ #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" +// Undefine to reduce the dependence on HAL +#undef USE_HAL_DRIVER +#include "portable/st/stm32_fsdev/dcd_stm32_fsdev.h" #endif /***************************************************** @@ -119,17 +119,17 @@ // 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 +#define MAX_EP_COUNT 8U #endif // 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 +#define DCD_STM32_BTABLE_BASE 0U #endif #ifndef DCD_STM32_BTABLE_SIZE -# define DCD_STM32_BTABLE_SIZE (FSDEV_PMA_SIZE - DCD_STM32_BTABLE_BASE) +#define DCD_STM32_BTABLE_SIZE (FSDEV_PMA_SIZE - DCD_STM32_BTABLE_BASE) #endif /*************************************************** @@ -145,20 +145,18 @@ TU_VERIFY_STATIC(((DCD_STM32_BTABLE_BASE) % 8) == 0, "BTABLE base must be aligne //--------------------------------------------------------------------+ // One of these for every EP IN & OUT, uses a bit of RAM.... -typedef struct -{ - uint8_t * buffer; - tu_fifo_t * ff; +typedef struct { + uint8_t *buffer; + tu_fifo_t *ff; uint16_t total_len; uint16_t queued_len; uint16_t max_packet_size; - uint8_t ep_idx; // index for USB_EPnR register + uint8_t ep_idx; // index for USB_EPnR register bool in_complete; // Workaround for ISO IN EP doesn't have interrupt mask } xfer_ctl_t; // EP allocator -typedef struct -{ +typedef struct { uint8_t ep_num; uint8_t ep_type; bool allocated[2]; @@ -178,7 +176,7 @@ static uint8_t remoteWakeCountdown; // When wake is requested // into the stack. static void dcd_handle_bus_reset(void); -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); static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr); static void dcd_ep_ctr_handler(void); @@ -189,14 +187,15 @@ 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_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); +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); //--------------------------------------------------------------------+ // Inline helper //--------------------------------------------------------------------+ -TU_ATTR_ALWAYS_INLINE static inline xfer_ctl_t* xfer_ctl_ptr(uint32_t ep_addr) { +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 @@ -209,7 +208,7 @@ TU_ATTR_ALWAYS_INLINE static inline xfer_ctl_t* xfer_ctl_ptr(uint32_t ep_addr) { // Controller API //--------------------------------------------------------------------+ -void dcd_init (uint8_t rhport) +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 */ @@ -217,13 +216,13 @@ 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 + for (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(uint32_t i = 0; i<200; i++) // should be a few us + for (uint32_t i = 0; i < 200; i++) // should be a few us { asm("NOP"); } @@ -231,29 +230,29 @@ void dcd_init (uint8_t rhport) 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 + for (uint32_t i = 0; i < 200; i++) // should be a few us { asm("NOP"); } 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) // 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 - for(uint32_t i=0; iCNTR |= USB_CNTR_RESETM | USB_CNTR_ESOFM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM; dcd_handle_bus_reset(); // Enable pull-up if supported - if ( dcd_connect ) dcd_connect(rhport); + if (dcd_connect) + dcd_connect(rhport); } // Define only on MCU with internal pull-up. BSP can define on MCU without internal PU. @@ -262,14 +261,14 @@ void dcd_init (uint8_t rhport) // Disable internal D+ PU void dcd_disconnect(uint8_t rhport) { - (void) rhport; + (void)rhport; USB->BCDR &= ~(USB_BCDR_DPPU); } // Enable internal D+ PU void dcd_connect(uint8_t rhport) { - (void) rhport; + (void)rhport; USB->BCDR |= USB_BCDR_DPPU; } @@ -277,60 +276,54 @@ void dcd_connect(uint8_t rhport) // Disable internal D+ PU void dcd_disconnect(uint8_t rhport) { - (void) rhport; + (void)rhport; SYSCFG->PMC &= ~(SYSCFG_PMC_USB_PU); } // Enable internal D+ PU void dcd_connect(uint8_t rhport) { - (void) rhport; + (void)rhport; SYSCFG->PMC |= SYSCFG_PMC_USB_PU; } #endif void dcd_sof_enable(uint8_t rhport, bool en) { - (void) rhport; - (void) en; + (void)rhport; + (void)en; - if (en) - { + if (en) { USB->CNTR |= USB_CNTR_SOFM; - } - else - { + } else { USB->CNTR &= ~USB_CNTR_SOFM; } } // Enable device interrupt -void dcd_int_enable (uint8_t rhport) +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 +#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) - { +// 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 + } else +#endif { NVIC_EnableIRQ(USB_HP_CAN_TX_IRQn); NVIC_EnableIRQ(USB_LP_CAN_RX0_IRQn); @@ -347,14 +340,14 @@ void dcd_int_enable (uint8_t rhport) 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 +#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); + NVIC_EnableIRQ(USB_DRD_FS_IRQn); #elif CFG_TUSB_MCU == OPT_MCU_STM32WB NVIC_EnableIRQ(USB_HP_IRQn); @@ -364,7 +357,7 @@ void dcd_int_enable (uint8_t rhport) NVIC_EnableIRQ(USB_FS_IRQn); #else - #error Unknown arch in USB driver +#error Unknown arch in USB driver #endif } @@ -373,24 +366,21 @@ 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 +#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) - { +// 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 + } else +#endif { NVIC_DisableIRQ(USB_HP_CAN_TX_IRQn); NVIC_DisableIRQ(USB_LP_CAN_RX0_IRQn); @@ -407,14 +397,14 @@ void dcd_int_disable(uint8_t rhport) 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 +#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); + NVIC_DisableIRQ(USB_DRD_FS_IRQn); #elif CFG_TUSB_MCU == OPT_MCU_STM32WB NVIC_DisableIRQ(USB_HP_IRQn); @@ -424,7 +414,7 @@ void dcd_int_disable(uint8_t rhport) NVIC_DisableIRQ(USB_FS_IRQn); #else - #error Unknown arch in USB driver +#error Unknown arch in USB driver #endif // CMSIS has a membar after disabling interrupts @@ -433,8 +423,8 @@ void dcd_int_disable(uint8_t 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; + (void)rhport; + (void)dev_addr; // Respond with status dcd_edpt_xfer(rhport, TUSB_DIR_IN_MASK | 0x00, NULL, 0); @@ -445,43 +435,36 @@ void dcd_set_address(uint8_t rhport, uint8_t dev_addr) void dcd_remote_wakeup(uint8_t rhport) { - (void) 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, +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 -}; + .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, +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 -}; + .bEndpointAddress = 0x80, + .bmAttributes = {.xfer = TUSB_XFER_CONTROL}, + .wMaxPacketSize = CFG_TUD_ENDPOINT0_SIZE, + .bInterval = 0}; static void dcd_handle_bus_reset(void) { //__IO uint16_t * const epreg = &(EPREG(0)); USB->DADDR = 0u; // disable USB peripheral by clearing the EF flag - for(uint32_t i=0; iDADDR = USB_DADDR_EF; // Set enable flag, and leaving the device address as zero. } @@ -510,18 +493,18 @@ static void dcd_ep_ctr_tx_handler(uint32_t wIstr) // 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) - { + if ((wEPRegVal & USB_EP_CTR_TX) == 0U) { return; } /* clear int flag */ pcd_clear_tx_ep_ctr(USB, EPindex); - xfer_ctl_t * xfer = xfer_ctl_ptr(ep_addr); + xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); /* Ignore spurious int */ - if(xfer->in_complete) return; + if (xfer->in_complete) + return; xfer->in_complete = true; if ((wEPRegVal & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS) { @@ -532,11 +515,10 @@ static void dcd_ep_ctr_tx_handler(uint32_t wIstr) } } - if((xfer->total_len != xfer->queued_len)) /* TX not complete */ + if ((xfer->total_len != xfer->queued_len)) /* TX not complete */ { dcd_transmit_packet(xfer, EPindex); - } - else /* TX Complete */ + } else /* TX Complete */ { dcd_event_xfer_complete(0, ep_addr, xfer->total_len, XFER_RESULT_SUCCESS, true); } @@ -544,8 +526,9 @@ static void dcd_ep_ctr_tx_handler(uint32_t wIstr) // 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) { - #ifdef FSDEV_BUS_32BIT +static void dcd_ep_ctr_rx_handler(uint32_t wIstr) +{ +#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: @@ -564,7 +547,7 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) { while (cycle_count > 0U) { cycle_count--; // each count take 2 cycle (1 cycle for sub, 1 cycle for compare/jump) } - #endif +#endif uint32_t EPindex = wIstr & USB_ISTR_EP_ID; uint32_t wEPRegVal = pcd_get_endpoint(USB, EPindex); @@ -574,34 +557,32 @@ 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) { + if ((wEPRegVal & USB_EP_CTR_RX) == 0U) { return; } - if((ep_addr == 0U) && ((wEPRegVal & USB_EP_SETUP) != 0U)) /* Setup packet */ + if ((ep_addr == 0U) && ((wEPRegVal & USB_EP_SETUP) != 0U)) /* Setup packet */ { uint32_t count = pcd_get_ep_rx_cnt(USB, EPindex); /* Get SETUP Packet*/ - if(count == 8) // Setup packet should always be 8 bytes. If not, ignore it, and try again. + if (count == 8) // Setup packet should always be 8 bytes. If not, ignore it, and try again. { // Must reset EP to NAK (in case it had been stalling) (though, maybe too late here) - pcd_set_ep_rx_status(USB,0u,USB_EP_RX_NAK); - pcd_set_ep_tx_status(USB,0u,USB_EP_TX_NAK); + pcd_set_ep_rx_status(USB, 0u, USB_EP_RX_NAK); + pcd_set_ep_tx_status(USB, 0u, USB_EP_TX_NAK); #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 + pcd_get_ep_rx_address(USB, EPindex)), 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_event_setup_received(0, (uint8_t*)userMemBuf, true); + dcd_read_packet_memory(userMemBuf, pcd_get_ep_rx_address(USB, EPindex), 8); + dcd_event_setup_received(0, (uint8_t *)userMemBuf, true); #endif } - } - else - { + } else { // Clear RX CTR interrupt flag - if(ep_addr != 0u) { + if (ep_addr != 0u) { pcd_clear_rx_ep_ctr(USB, EPindex); } @@ -623,36 +604,29 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) { TU_ASSERT(count <= xfer->max_packet_size, /**/); - if (count != 0U) - { - if (xfer->ff) - { + if (count != 0U) { + if (xfer->ff) { dcd_read_packet_memory_ff(xfer->ff, addr, count); - } - else - { + } else { dcd_read_packet_memory(&(xfer->buffer[xfer->queued_len]), addr, count); } xfer->queued_len = (uint16_t)(xfer->queued_len + count); } - if ((count < xfer->max_packet_size) || (xfer->queued_len == xfer->total_len)) - { + if ((count < xfer->max_packet_size) || (xfer->queued_len == xfer->total_len)) { /* RX COMPLETE */ dcd_event_xfer_complete(0, ep_addr, xfer->queued_len, XFER_RESULT_SUCCESS, true); // Though the host could still send, we don't know. // Does the bulk pipe need to be reset to valid to allow for a ZLP? - } - else - { + } 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 = remaining >= xfer->max_packet_size ? xfer->max_packet_size : remaining; pcd_set_ep_rx_cnt(USB, EPindex, cnt); - pcd_set_ep_rx_cnt(USB, EPindex,remaining); + pcd_set_ep_rx_cnt(USB, EPindex, remaining); } pcd_set_ep_rx_status(USB, EPindex, USB_EP_RX_VALID); } @@ -661,15 +635,15 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) { // 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) - { + if (ep_addr == 0u) { // Always be prepared for a status packet... pcd_set_ep_rx_cnt(USB, EPindex, CFG_TUD_ENDPOINT0_SIZE); pcd_clear_rx_ep_ctr(USB, EPindex); } } -static void dcd_ep_ctr_handler(void) { +static void dcd_ep_ctr_handler(void) +{ uint32_t wIstr; /* stay in loop while pending interrupts */ @@ -684,26 +658,27 @@ static void dcd_ep_ctr_handler(void) { } } -void dcd_int_handler(uint8_t rhport) { +void dcd_int_handler(uint8_t rhport) +{ - (void) rhport; + (void)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; - // unused IRQs: (USB_ISTR_PMAOVR | USB_ISTR_ERR | USB_ISTR_L1REQ ) + // 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 ) // 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) { + if (int_status & USB_ISTR_SOF) { USB->ISTR = (fsdev_bus_t)~USB_ISTR_SOF; dcd_event_sof(0, USB->FNR & USB_FNR_FN, true); } - if(int_status & USB_ISTR_RESET) { + if (int_status & USB_ISTR_RESET) { // USBRST is start of reset. USB->ISTR = (fsdev_bus_t)~USB_ISTR_RESET; dcd_handle_bus_reset(); @@ -711,15 +686,13 @@ 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) - { + 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) - { + if (int_status & USB_ISTR_WKUP) { USB->CNTR &= ~USB_CNTR_LPMODE; USB->CNTR &= ~USB_CNTR_FSUSP; @@ -727,8 +700,7 @@ void dcd_int_handler(uint8_t rhport) { dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); } - if (int_status & USB_ISTR_SUSP) - { + if (int_status & USB_ISTR_SUSP) { /* Suspend is asserted for both suspend and unplug events. without Vbus monitoring, * these events cannot be differentiated, so we only trigger suspend. */ @@ -741,13 +713,11 @@ void dcd_int_handler(uint8_t rhport) { dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); } - if(int_status & USB_ISTR_ESOF) { - if(remoteWakeCountdown == 1u) - { + if (int_status & USB_ISTR_ESOF) { + if (remoteWakeCountdown == 1u) { USB->CNTR &= ~USB_CNTR_RESUME; } - if(remoteWakeCountdown > 0u) - { + if (remoteWakeCountdown > 0u) { remoteWakeCountdown--; } USB->ISTR = (fsdev_bus_t)~USB_ISTR_ESOF; @@ -760,15 +730,12 @@ 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; + (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; + 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; @@ -793,7 +760,7 @@ static uint32_t dcd_pma_alloc(uint16_t length, bool dbuf) uint32_t addr = ep_buf_ptr; ep_buf_ptr = (uint16_t)(ep_buf_ptr + length); // increment buffer pointer - if(dbuf) { + if (dbuf) { addr |= ((uint32_t)ep_buf_ptr) << 16; ep_buf_ptr = (uint16_t)(ep_buf_ptr + length); // increment buffer pointer } @@ -810,31 +777,21 @@ static uint32_t dcd_pma_alloc(uint16_t length, bool dbuf) 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); + 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 < STFSDEV_EP_COUNT; i++) { // Check if already allocated - if(ep_alloc_status[i].allocated[dir] && - ep_alloc_status[i].ep_type == ep_type && - ep_alloc_status[i].ep_num == epnum) - { + if (ep_alloc_status[i].allocated[dir] && ep_alloc_status[i].ep_type == ep_type && ep_alloc_status[i].ep_num == epnum) { return i; } // If EP of current direction is not allocated // Except for ISO endpoint, both direction should be free - if(!ep_alloc_status[i].allocated[dir] && - (ep_type != TUSB_XFER_ISOCHRONOUS || !ep_alloc_status[i].allocated[dir ^ 1])) - { + if (!ep_alloc_status[i].allocated[dir] && (ep_type != TUSB_XFER_ISOCHRONOUS || !ep_alloc_status[i].allocated[dir ^ 1])) { // Check if EP number is the same - if(ep_alloc_status[i].ep_num == 0xFF || - ep_alloc_status[i].ep_num == epnum) - { + if (ep_alloc_status[i].ep_num == 0xFF || ep_alloc_status[i].ep_num == epnum) { // One EP pair has to be the same type - if(ep_alloc_status[i].ep_type == 0xFF || - ep_alloc_status[i].ep_type == ep_type) - { + if (ep_alloc_status[i].ep_type == 0xFF || ep_alloc_status[i].ep_type == ep_type) { ep_alloc_status[i].ep_num = epnum; ep_alloc_status[i].ep_type = ep_type; ep_alloc_status[i].allocated[dir] = true; @@ -852,11 +809,11 @@ 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 *p_endpoint_desc) { (void)rhport; uint8_t const ep_idx = dcd_ep_alloc(p_endpoint_desc->bEndpointAddress, p_endpoint_desc->bmAttributes.xfer); - uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); + uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); const uint16_t packet_size = tu_edpt_packet_size(p_endpoint_desc); const uint16_t buffer_size = pcd_aligned_buffer_size(packet_size); uint16_t pma_addr; @@ -869,7 +826,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) TU_ASSERT(p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS); // Set type - switch(p_endpoint_desc->bmAttributes.xfer) { + switch (p_endpoint_desc->bmAttributes.xfer) { case TUSB_XFER_CONTROL: wType = USB_EP_CONTROL; break; @@ -891,15 +848,13 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) /* Create a packet memory buffer area. */ pma_addr = dcd_pma_alloc(buffer_size, false); - if(dir == TUSB_DIR_IN) - { + if (dir == TUSB_DIR_IN) { pcd_set_ep_tx_address(USB, ep_idx, pma_addr); pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_NAK); pcd_clear_tx_dtog(USB, ep_idx); } - if(dir == TUSB_DIR_OUT) - { + if (dir == TUSB_DIR_OUT) { pcd_set_ep_rx_address(USB, ep_idx, pma_addr); pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_NAK); pcd_clear_rx_dtog(USB, ep_idx); @@ -911,9 +866,9 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) return true; } -void dcd_edpt_close_all (uint8_t rhport) +void dcd_edpt_close_all(uint8_t rhport) { - (void) rhport; + (void)rhport; // TODO implement dcd_edpt_close_all() } @@ -928,16 +883,13 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { (void)rhport; - xfer_ctl_t * xfer = xfer_ctl_ptr(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); + uint8_t const dir = tu_edpt_dir(ep_addr); - if(dir == TUSB_DIR_IN) - { + if (dir == TUSB_DIR_IN) { pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_DIS); - } - else - { + } else { pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_DIS); } } @@ -970,11 +922,11 @@ bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet 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 *p_endpoint_desc) { (void)rhport; uint8_t const ep_idx = xfer_ctl_ptr(p_endpoint_desc->bEndpointAddress)->ep_idx; - uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); + uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); const uint16_t packet_size = tu_edpt_packet_size(p_endpoint_desc); pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_DIS); @@ -985,7 +937,7 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpo pcd_clear_tx_dtog(USB, ep_idx); pcd_clear_rx_dtog(USB, ep_idx); - if(dir == TUSB_DIR_IN) { + if (dir == TUSB_DIR_IN) { pcd_rx_dtog(USB, ep_idx); } else { pcd_tx_dtog(USB, ep_idx); @@ -998,11 +950,11 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpo // 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) // max packet size for FS transfer + if (len > xfer->max_packet_size) // max packet size for FS transfer { len = xfer->max_packet_size; } @@ -1023,12 +975,9 @@ static void dcd_transmit_packet(xfer_ctl_t * xfer, uint16_t ep_ix) pcd_set_ep_tx_cnt(USB, ep_ix, len); } - if (xfer->ff) - { + if (xfer->ff) { dcd_write_packet_memory_ff(xfer->ff, addr_ptr, len); - } - else - { + } else { dcd_write_packet_memory(addr_ptr, &(xfer->buffer[xfer->queued_len]), len); } xfer->queued_len = (uint16_t)(xfer->queued_len + len); @@ -1041,19 +990,17 @@ static void dcd_transmit_packet(xfer_ctl_t * xfer, uint16_t ep_ix) static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr) { - (void) rhport; + (void)rhport; - xfer_ctl_t * xfer = xfer_ctl_ptr(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); + uint8_t const dir = tu_edpt_dir(ep_addr); - if ( dir == TUSB_DIR_OUT ) - { + if (dir == TUSB_DIR_OUT) { // 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; + if (ep_idx == 0 && xfer->buffer == NULL) { + xfer->buffer = (uint8_t *)_setup_packet; } uint32_t cnt = xfer->total_len > xfer->max_packet_size ? xfer->max_packet_size : xfer->total_len; @@ -1067,75 +1014,68 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr) } pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_VALID); - } - else // IN + } else // IN { - dcd_transmit_packet(xfer,ep_idx); + dcd_transmit_packet(xfer, ep_idx); } 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_ctl_t *xfer = xfer_ctl_ptr(ep_addr); xfer->buffer = buffer; - xfer->ff = NULL; + xfer->ff = NULL; xfer->total_len = total_bytes; xfer->queued_len = 0; 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_ctl_t *xfer = xfer_ctl_ptr(ep_addr); xfer->buffer = NULL; - xfer->ff = ff; + xfer->ff = ff; xfer->total_len = total_bytes; xfer->queued_len = 0; 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); + 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); + uint8_t const dir = tu_edpt_dir(ep_addr); - if (dir == TUSB_DIR_IN) - { // IN + if (dir == TUSB_DIR_IN) { // IN pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_STALL); - } - else - { // OUT + } else { // OUT pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_STALL); } } -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); + 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); + uint8_t const dir = tu_edpt_dir(ep_addr); - if (dir == TUSB_DIR_IN) - { // IN - if (pcd_get_eptype(USB, ep_idx) != USB_EP_ISOCHRONOUS) { + 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) { + } 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. */ @@ -1146,8 +1086,8 @@ 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; - volatile uint32_t* dst32 = (volatile uint32_t*)(USB_PMAADDR + dst); + const uint8_t *srcVal = 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); @@ -1155,18 +1095,15 @@ static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, ui } wNBytes = wNBytes & 0x03; - if (wNBytes) - { + if (wNBytes) { uint32_t wrVal = *srcVal; wNBytes--; - if (wNBytes) - { + if (wNBytes) { wrVal |= *++srcVal << 8; wNBytes--; - if (wNBytes) - { + if (wNBytes) { wrVal |= *++srcVal << 16; } } @@ -1179,20 +1116,20 @@ static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, ui #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 byte-access for user memory (so support non-aligned buffers) - * 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 - */ + * @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. + * @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) { uint32_t n = (uint32_t)wNBytes >> 1U; uint16_t temp1, temp2; - const uint8_t * srcVal; + 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. @@ -1201,18 +1138,16 @@ static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, ui srcVal = src; pdwVal = &pma[FSDEV_PMA_STRIDE * (dst >> 1)]; - while (n--) - { + while (n--) { temp1 = (uint16_t)*srcVal; srcVal++; - temp2 = temp1 | ((uint16_t)(((uint16_t)(*srcVal)) << 8U)) ; + temp2 = temp1 | ((uint16_t)(((uint16_t)(*srcVal)) << 8U)); *pdwVal = temp2; pdwVal += FSDEV_PMA_STRIDE; srcVal++; } - if (wNBytes) - { + if (wNBytes) { temp1 = *srcVal; *pdwVal = temp1; } @@ -1222,42 +1157,39 @@ static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, ui #endif /** - * @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 - */ -static bool dcd_write_packet_memory_ff(tu_fifo_t * ff, uint16_t dst, uint16_t wNBytes) + * @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 + */ +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); - uint16_t cnt_lin = TU_MIN(wNBytes, info.len_lin); + 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 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) - { + 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; + 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]; + 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; + for (; i < 4 && wCnt > 0; i++, wCnt--) { + tmp[i] = *(uint8_t *)info.ptr_wrap; + info.ptr_wrap = (uint8_t *)info.ptr_wrap + 1; } // Write unaligned buffer @@ -1266,32 +1198,29 @@ static bool dcd_write_packet_memory_ff(tu_fifo_t * ff, uint16_t dst, uint16_t wN // Copy rest of wrapped byte if (wCnt) - dcd_write_packet_memory(dst, info.ptr_wrap, wCnt); + dcd_write_packet_memory(dst, info.ptr_wrap, wCnt); } #else - if((cnt_lin & 0x01) && cnt_wrap) - { + 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; + 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); + 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); + dcd_write_packet_memory(dst, ((uint8_t *)info.ptr_wrap) + 1, cnt_wrap - 1); } #endif - else - { + else { // Copy linear part dcd_write_packet_memory(dst, info.ptr_lin, cnt_lin); dst += info.len_lin; - if(info.len_wrap) - { + if (info.len_wrap) { // Copy wrapped byte dcd_write_packet_memory(dst, info.ptr_wrap, cnt_wrap); } @@ -1305,8 +1234,8 @@ static bool dcd_write_packet_memory_ff(tu_fifo_t * ff, uint16_t dst, uint16_t wN #ifdef FSDEV_BUS_32BIT static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t wNBytes) { - uint8_t* dstVal = dst; - volatile uint32_t* src32 = (volatile uint32_t*)(USB_PMAADDR + src); + uint8_t *dstVal = 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++); @@ -1314,20 +1243,17 @@ static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t } wNBytes = wNBytes & 0x03; - if (wNBytes) - { + if (wNBytes) { uint32_t rdVal = *src32; *dstVal = tu_u32_byte0(rdVal); wNBytes--; - if (wNBytes) - { + if (wNBytes) { *++dstVal = tu_u32_byte1(rdVal); wNBytes--; - if (wNBytes) - { + if (wNBytes) { *++dstVal = tu_u32_byte2(rdVal); } } @@ -1337,11 +1263,11 @@ 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 - * @param wNBytes no. of bytes to be copied. - * @retval None - */ + * @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 + * @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; @@ -1351,18 +1277,16 @@ static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t uint32_t temp; pdwVal = &pma[FSDEV_PMA_STRIDE * (src >> 1)]; - uint8_t *dstVal = (uint8_t*)dst; + uint8_t *dstVal = (uint8_t *)dst; - while (n--) - { + while (n--) { temp = *pdwVal; pdwVal += FSDEV_PMA_STRIDE; *dstVal++ = ((temp >> 0) & 0xFF); *dstVal++ = ((temp >> 8) & 0xFF); } - if (wNBytes & 0x01) - { + if (wNBytes & 0x01) { temp = *pdwVal; pdwVal += FSDEV_PMA_STRIDE; *dstVal++ = ((temp >> 0) & 0xFF); @@ -1372,31 +1296,29 @@ static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t #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 - * @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) + * @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 + */ +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; - tu_fifo_get_write_info(ff, &info); // We want to read from the FIFO + 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_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) - { + 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; + 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]; @@ -1404,15 +1326,13 @@ static bool dcd_read_packet_memory_ff(tu_fifo_t * ff, uint16_t src, uint16_t wNB src += 4; uint32_t i; - for (i = 0; i < (cnt_lin & 0x03); i++) - { - ((uint8_t*)info.ptr_lin)[(cnt_lin &~0x03) + i] = tmp[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; + for (; i < 4 && wCnt > 0; i++, wCnt--) { + *(uint8_t *)info.ptr_wrap = tmp[i]; + info.ptr_wrap = (uint8_t *)info.ptr_wrap + 1; } // Copy rest of wrapped byte @@ -1420,32 +1340,29 @@ static bool dcd_read_packet_memory_ff(tu_fifo_t * ff, uint16_t src, uint16_t wNB dcd_read_packet_memory(info.ptr_wrap, src, wCnt); } #else - if((cnt_lin & 0x01) && cnt_wrap) - { + 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; + dcd_read_packet_memory(info.ptr_lin, src, cnt_lin & ~0x01); + src += cnt_lin & ~0x01; // Copy last linear byte & first wrapped byte uint8_t tmp[2]; dcd_read_packet_memory(tmp, src, 2); src += 2; - ((uint8_t*)info.ptr_lin)[cnt_lin - 1] = tmp[0]; - ((uint8_t*)info.ptr_wrap)[0] = tmp[1]; + ((uint8_t *)info.ptr_lin)[cnt_lin - 1] = tmp[0]; + ((uint8_t *)info.ptr_wrap)[0] = tmp[1]; // Copy rest of wrapped byte - dcd_read_packet_memory(((uint8_t*)info.ptr_wrap) + 1, src, cnt_wrap - 1); + dcd_read_packet_memory(((uint8_t *)info.ptr_wrap) + 1, src, cnt_wrap - 1); } #endif - else - { + else { // Copy linear part dcd_read_packet_memory(info.ptr_lin, src, cnt_lin); src += cnt_lin; - if(info.len_wrap) - { + if (info.len_wrap) { // Copy wrapped byte dcd_read_packet_memory(info.ptr_wrap, src, cnt_wrap); } From 5f4d6ae20c54eac6058f7071900d1c00f7f4d6f7 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Tue, 9 Apr 2024 23:09:43 +0200 Subject: [PATCH 270/454] Fix STM32L0 IAR build. --- hw/bsp/stm32l0/family.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/bsp/stm32l0/family.c b/hw/bsp/stm32l0/family.c index 212415744..a02482da5 100644 --- a/hw/bsp/stm32l0/family.c +++ b/hw/bsp/stm32l0/family.c @@ -163,7 +163,7 @@ uint32_t board_millis(void) void HardFault_Handler (void) { - asm("bkpt"); + __asm("BKPT #0\n"); } #ifdef USE_FULL_ASSERT From 0d4465a0983dc6eda1aa59efe4d4b0414aba97ff Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Tue, 9 Apr 2024 23:11:43 +0200 Subject: [PATCH 271/454] Optimize audio_4_channel_mic waveform data. --- .../device/audio_4_channel_mic/src/main.c | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/examples/device/audio_4_channel_mic/src/main.c b/examples/device/audio_4_channel_mic/src/main.c index 1de4f9dac..10e6fe88a 100644 --- a/examples/device/audio_4_channel_mic/src/main.c +++ b/examples/device/audio_4_channel_mic/src/main.c @@ -104,39 +104,39 @@ int main(void) // Generate dummy data #if CFG_TUD_AUDIO_ENABLE_ENCODING uint16_t * p_buff = i2s_dummy_buffer[0]; - uint16_t dataVal = 1; + 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++ = 60 + AUDIO_SAMPLE_RATE/1000 - dataVal; - dataVal++; + *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) ? 120:170; + *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)(sinf(t) * 25) + 200; + *p_buff++ = (uint16_t)((int16_t)(sinf(t) * 750) + 6000); } #else uint16_t * p_buff = i2s_dummy_buffer; - uint16_t dataVal = 1; + 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++ = 60 + AUDIO_SAMPLE_RATE/1000 - dataVal; - dataVal++; + *p_buff++ = 3200 + AUDIO_SAMPLE_RATE/1000 - dataVal; + dataVal+= 32; // CH3 square wave - *p_buff++ = cnt < (AUDIO_SAMPLE_RATE/1000/2) ? 120:170; + *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)(sinf(t) * 25) + 200; + *p_buff++ = (uint16_t)((int16_t)(sinf(t) * 750) + 6000); } #endif From 3ecabe3ebebbd896527619d27a785491ebe3421c Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Tue, 9 Apr 2024 23:55:38 +0200 Subject: [PATCH 272/454] Fix stm32h573i_dk button & led. --- hw/bsp/stm32h5/boards/stm32h573i_dk/board.h | 4 ++-- hw/bsp/stm32h5/family.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/bsp/stm32h5/boards/stm32h573i_dk/board.h b/hw/bsp/stm32h5/boards/stm32h573i_dk/board.h index 674cf8e2a..7baef6ca6 100644 --- a/hw/bsp/stm32h5/boards/stm32h573i_dk/board.h +++ b/hw/bsp/stm32h5/boards/stm32h573i_dk/board.h @@ -35,12 +35,12 @@ extern "C" { // LED #define LED_PORT GPIOI #define LED_PIN GPIO_PIN_9 -#define LED_STATE_ON 0 +#define LED_STATE_ON 1 // Button #define BUTTON_PORT GPIOC #define BUTTON_PIN GPIO_PIN_13 -#define BUTTON_STATE_ACTIVE 0 +#define BUTTON_STATE_ACTIVE 1 // UART Enable for STLink VCOM #define UART_DEV USART1 diff --git a/hw/bsp/stm32h5/family.c b/hw/bsp/stm32h5/family.c index 81c0ef4ce..02500db4e 100644 --- a/hw/bsp/stm32h5/family.c +++ b/hw/bsp/stm32h5/family.c @@ -73,10 +73,10 @@ void board_init(void) { __HAL_RCC_GPIOE_CLK_ENABLE(); #endif #ifdef __HAL_RCC_GPIOG_CLK_ENABLE - __HAL_RCC_GPIOE_CLK_ENABLE(); + __HAL_RCC_GPIOG_CLK_ENABLE(); #endif #ifdef __HAL_RCC_GPIOI_CLK_ENABLE - __HAL_RCC_GPIOE_CLK_ENABLE(); + __HAL_RCC_GPIOI_CLK_ENABLE(); #endif UART_CLK_EN(); From 724ef1af8d948dc65815b48564b351eeeb270f77 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 10 Apr 2024 09:58:43 +0700 Subject: [PATCH 273/454] set txfifo empty level to complete and change back fifo tx to normal size --- src/portable/synopsys/dwc2/dcd_dwc2.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 69d96aff0..d01d9645b 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -154,9 +154,11 @@ static bool fifo_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t packet_size) { dwc2->grxfsiz = sz; } } else { - // The fifo-empty interrupt fires when the interrupt is half empty. In order + // 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. - fifo_size = fifo_size * 2; + 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); @@ -596,13 +598,13 @@ void dcd_init(uint8_t rhport) { int_mask = dwc2->gotgint; dwc2->gotgint |= int_mask; - // Configure TX FIFO to set the TX FIFO empty interrupt when half-empty - dwc2->gahbcfg &= ~GAHBCFG_TXFELVL; - // Required as part of core initialization. dwc2->gintmsk = GINTMSK_OTGINT | GINTMSK_RXFLVLM | 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; From 1e41b9725a946eb6bbbd5cc96b804dbca0bcf7fa Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 10 Apr 2024 10:13:36 +0700 Subject: [PATCH 274/454] remove the usage of TU_BIT() and TU_GENMASK() from tusb_types.h --- src/common/tusb_types.h | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index 2c5dce723..b571f9b72 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -24,12 +24,8 @@ * This file is part of the TinyUSB stack. */ -/** \ingroup group_usb_definitions - * \defgroup USBDef_Type USB Types - * @{ */ - -#ifndef _TUSB_TYPES_H_ -#define _TUSB_TYPES_H_ +#ifndef TUSB_TYPES_H_ +#define TUSB_TYPES_H_ #include #include @@ -212,8 +208,8 @@ typedef enum { } device_capability_type_t; enum { - TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP = TU_BIT(5), - TUSB_DESC_CONFIG_ATT_SELF_POWERED = TU_BIT(6), + TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP = 1u << 5, + TUSB_DESC_CONFIG_ATT_SELF_POWERED = 1u << 6, }; #define TUSB_DESC_CONFIG_POWER_MA(x) ((x)/2) @@ -274,11 +270,11 @@ TU_ATTR_BIT_FIELD_ORDER_BEGIN typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. uint8_t bDescriptorType ; ///< DEVICE Descriptor Type. - uint16_t bcdUSB ; ///< BUSB Specification Release Number in Binary-Coded Decimal (i.e., 2.10 is 210H). This field identifies the release of the USB Specification with which the device and its descriptors are compliant. + uint16_t bcdUSB ; ///< BUSB Specification Release Number in Binary-Coded Decimal (i.e., 2.10 is 210H). - uint8_t bDeviceClass ; ///< Class code (assigned by the USB-IF). \li If this field is reset to zero, each interface within a configuration specifies its own class information and the various interfaces operate independently. \li If this field is set to a value between 1 and FEH, the device supports different class specifications on different interfaces and the interfaces may not operate independently. This value identifies the class definition used for the aggregate interfaces. \li If this field is set to FFH, the device class is vendor-specific. - uint8_t bDeviceSubClass ; ///< Subclass code (assigned by the USB-IF). These codes are qualified by the value of the bDeviceClass field. \li If the bDeviceClass field is reset to zero, this field must also be reset to zero. \li If the bDeviceClass field is not set to FFH, all values are reserved for assignment by the USB-IF. - uint8_t bDeviceProtocol ; ///< Protocol code (assigned by the USB-IF). These codes are qualified by the value of the bDeviceClass and the bDeviceSubClass fields. If a device supports class-specific protocols on a device basis as opposed to an interface basis, this code identifies the protocols that the device uses as defined by the specification of the device class. \li If this field is reset to zero, the device does not use class-specific protocols on a device basis. However, it may use classspecific protocols on an interface basis. \li If this field is set to FFH, the device uses a vendor-specific protocol on a device basis. + uint8_t bDeviceClass ; ///< Class code (assigned by the USB-IF). + uint8_t bDeviceSubClass ; ///< Subclass code (assigned by the USB-IF). + uint8_t bDeviceProtocol ; ///< Protocol code (assigned by the USB-IF). uint8_t bMaxPacketSize0 ; ///< Maximum packet size for endpoint zero (only 8, 16, 32, or 64 are valid). For HS devices is fixed to 64. uint16_t idVendor ; ///< Vendor ID (assigned by the USB-IF). @@ -493,15 +489,10 @@ TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_edpt_addr(uint8_t num, uint8_t di } TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_edpt_packet_size(tusb_desc_endpoint_t const* desc_ep) { - return tu_le16toh(desc_ep->wMaxPacketSize) & TU_GENMASK(10, 0); + return tu_le16toh(desc_ep->wMaxPacketSize) & 0x7FF; } #if CFG_TUSB_DEBUG -TU_ATTR_ALWAYS_INLINE static inline const char *tu_edpt_dir_str(tusb_dir_t dir) { - tu_static const char *str[] = {"out", "in"}; - return str[dir]; -} - TU_ATTR_ALWAYS_INLINE static inline const char *tu_edpt_type_str(tusb_xfer_type_t t) { tu_static const char *str[] = {"control", "isochronous", "bulk", "interrupt"}; return str[t]; @@ -541,6 +532,4 @@ uint8_t const * tu_desc_find3(uint8_t const* desc, uint8_t const* end, uint8_t b } #endif -#endif /* _TUSB_TYPES_H_ */ - -/** @} */ +#endif // TUSB_TYPES_H_ From 804a73a454f382ef7dd5377e6a564f516196fa5d Mon Sep 17 00:00:00 2001 From: Luke A Date: Mon, 14 Aug 2023 21:58:20 -0400 Subject: [PATCH 275/454] Adding tuh_hid_get_report(...) to hid_host.h This allows USB host functionality to call HID_REQ_CONTROL_GET_REPORT on the IN Endpoint, and read the report buffer in the callback. --- src/class/hid/hid_host.c | 44 ++++++++++++++++++++++++++++++++++++++++ src/class/hid/hid_host.h | 8 ++++++++ 2 files changed, 52 insertions(+) diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 621fb2a55..115a8a4df 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -222,6 +222,50 @@ bool tuh_hid_set_protocol(uint8_t daddr, uint8_t idx, uint8_t protocol) { return _hidh_set_protocol(daddr, p_hid->itf_num, protocol, set_protocol_complete, 0); } +static void get_report_complete(tuh_xfer_t* xfer) { + TU_LOG_DRV("HID Get Report complete\r\n"); + + if (tuh_hid_get_report_complete_cb) { + uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); + uint8_t const idx = tuh_hid_itf_get_index(xfer->daddr, itf_num); + + uint8_t const report_type = tu_u16_high(xfer->setup->wValue); + uint8_t const report_id = tu_u16_low(xfer->setup->wValue); + + tuh_hid_get_report_complete_cb(xfer->daddr, idx, report_id, report_type, + (xfer->result == XFER_RESULT_SUCCESS) ? xfer->setup->wLength : 0); + } +} + +bool tuh_hid_get_report(uint8_t daddr, uint8_t idx, uint8_t report_id, uint8_t report_type, void* report, uint16_t len) { + hidh_interface_t* p_hid = get_hid_itf(daddr, idx); + TU_VERIFY(p_hid); + TU_LOG_DRV("HID Get Report: id = %u, type = %u, len = %u\r\n", report_id, report_type, len); + + tusb_control_request_t const request = { + .bmRequestType_bit = { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_IN + }, + .bRequest = HID_REQ_CONTROL_GET_REPORT, + .wValue = tu_htole16(tu_u16(report_type, report_id)), + .wIndex = tu_htole16((uint16_t) p_hid->itf_num), + .wLength = len + }; + + tuh_xfer_t xfer = { + .daddr = daddr, + .ep_addr = 0, + .setup = &request, + .buffer = report, + .complete_cb = get_report_complete, + .user_data = 0 + }; + + return tuh_control_xfer(&xfer); +} + static void set_report_complete(tuh_xfer_t* xfer) { TU_LOG_DRV("HID Set Report complete\r\n"); diff --git a/src/class/hid/hid_host.h b/src/class/hid/hid_host.h index 0902bf1af..9681c704b 100644 --- a/src/class/hid/hid_host.h +++ b/src/class/hid/hid_host.h @@ -105,6 +105,10 @@ void tuh_hid_set_default_protocol(uint8_t protocol); // This function is only supported by Boot interface (tuh_n_hid_interface_protocol() != NONE) bool tuh_hid_set_protocol(uint8_t dev_addr, uint8_t idx, uint8_t protocol); +// Get Report using control endpoint +// report_type is either Input, Output or Feature, (value from hid_report_type_t) +bool tuh_hid_get_report(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type, void* report, uint16_t len); + // Set Report using control endpoint // report_type is either Input, Output or Feature, (value from hid_report_type_t) bool tuh_hid_set_report(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type, @@ -153,6 +157,10 @@ void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t idx, uint8_t const* re // Invoked when sent report to device successfully via interrupt endpoint TU_ATTR_WEAK void tuh_hid_report_sent_cb(uint8_t dev_addr, uint8_t idx, uint8_t const* report, uint16_t len); +// Invoked when Get Report to device via either control endpoint +// len = 0 indicate there is error in the transfer e.g stalled response +TU_ATTR_WEAK void tuh_hid_get_report_complete_cb(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type, uint16_t len); + // Invoked when Sent Report to device via either control endpoint // len = 0 indicate there is error in the transfer e.g stalled response TU_ATTR_WEAK void tuh_hid_set_report_complete_cb(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type, uint16_t len); From a173e6ed138cc6f696ab219913c7cf8107c2e9ed Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 10 Apr 2024 17:02:35 +0700 Subject: [PATCH 276/454] revert pr2245 --- src/portable/renesas/rusb2/dcd_rusb2.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/portable/renesas/rusb2/dcd_rusb2.c b/src/portable/renesas/rusb2/dcd_rusb2.c index 24edc30e7..3ec1b70b5 100644 --- a/src/portable/renesas/rusb2/dcd_rusb2.c +++ b/src/portable/renesas/rusb2/dcd_rusb2.c @@ -266,14 +266,6 @@ static void pipe_read_packet_ff(rusb2_reg_t * rusb, tu_fifo_t *f, volatile void tu_fifo_advance_write_pointer(f, count); } - -static bool wait_pipe_fifo_empty(rusb2_reg_t* rusb, uint8_t num) { - TU_ASSERT(num); - while( (rusb->PIPE_CTR[num-1] & RUSB2_PIPE_CTR_INBUFM_Msk) > 0 ) {} - return true; -} - - //--------------------------------------------------------------------+ // Pipe Transfer //--------------------------------------------------------------------+ @@ -347,7 +339,6 @@ static bool pipe_xfer_in(rusb2_reg_t* rusb, unsigned num) const unsigned rem = pipe->remaining; if (!rem) { - wait_pipe_fifo_empty(rusb, num); pipe->buf = NULL; return true; } From fb69d80e70c5a3d89606bb503622837fdf8fae4a Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 10 Apr 2024 18:26:56 +0700 Subject: [PATCH 277/454] use for loop instead of__builtin_ctz() which is not portable (e.g with ccrx) --- src/portable/renesas/rusb2/dcd_rusb2.c | 52 +++++++++++--------------- 1 file changed, 22 insertions(+), 30 deletions(-) diff --git a/src/portable/renesas/rusb2/dcd_rusb2.c b/src/portable/renesas/rusb2/dcd_rusb2.c index 3ec1b70b5..0d53b7a7b 100644 --- a/src/portable/renesas/rusb2/dcd_rusb2.c +++ b/src/portable/renesas/rusb2/dcd_rusb2.c @@ -89,39 +89,39 @@ static dcd_data_t _dcd; // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ -// Transfer conditions specifiable for each pipe: +// Transfer conditions specifiable for each pipe for most MCUs // - Pipe 0: Control transfer with 64-byte single buffer -// - Pipes 1 and 2: Bulk isochronous transfer continuous transfer mode with programmable buffer size up -// to 2 KB and optional double buffer -// - Pipes 3 to 5: Bulk transfer continuous transfer mode with programmable buffer size up to 2 KB and -// optional double buffer -// - Pipes 6 to 9: Interrupt transfer with 64-byte single buffer +// - Pipes 1 and 2: Bulk or ISO +// - Pipes 3 to 5: Bulk +// - Pipes 6 to 9: Interrupt +// +// Note: for small mcu such as +// - RA2A1: only pipe 4-7 are available, and no support for ISO + enum { - PIPE_1ST_BULK = 3, - PIPE_1ST_INTERRUPT = 6, + PIPE_LAST_ISO = 2, + PIPE_LAST_BULK = 5, + PIPE_LAST_INTERRUPT = 9, PIPE_COUNT = 10, }; -static unsigned find_pipe(unsigned xfer) -{ - switch (xfer) { +static unsigned find_pipe(unsigned xfer_type) { + switch (xfer_type) { case TUSB_XFER_ISOCHRONOUS: - for (int i = 1; i < PIPE_1ST_BULK; ++i) { + for (int i = PIPE_LAST_ISO; i > 0; i--) { if (0 == _dcd.pipe[i].ep) return i; } break; case TUSB_XFER_BULK: - for (int i = PIPE_1ST_BULK; i < PIPE_1ST_INTERRUPT; ++i) { - if (0 == _dcd.pipe[i].ep) return i; - } - for (int i = 1; i < PIPE_1ST_BULK; ++i) { + // find backward since only pipe 1, 2 support ISO + for (int i = PIPE_LAST_BULK; i > 0; i--) { if (0 == _dcd.pipe[i].ep) return i; } break; case TUSB_XFER_INTERRUPT: - for (int i = PIPE_1ST_INTERRUPT; i < PIPE_COUNT; ++i) { + for(int i = PIPE_LAST_INTERRUPT; i > PIPE_LAST_BULK; i--) { if (0 == _dcd.pipe[i].ep) return i; } break; @@ -1025,20 +1025,12 @@ void dcd_int_handler(uint8_t rhport) unsigned s = rusb->BRDYSTS & m; /* clear active bits (don't write 0 to already cleared bits according to the HW manual) */ rusb->BRDYSTS = ~s; - while (s) { -#if defined(__CCRX__) - static const int Mod37BitPosition[] = { - -1, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13, 4, - 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9, 5, - 20, 8, 19, 18 - }; - const unsigned num = Mod37BitPosition[(-s & s) % 37]; -#else - const unsigned num = __builtin_ctz(s); -#endif - process_pipe_brdy(rhport, num); - s &= ~TU_BIT(num); + for (unsigned pipe = 0; pipe < PIPE_COUNT; ++pipe) { + if (tu_bit_test(s, pipe)) { + process_pipe_brdy(rhport, pipe); + s = tu_bit_clear(s, pipe); + } } } } From 241e436d19d5ee400decc0d6a56ed4ab2a21fa46 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 10 Apr 2024 19:17:23 +0700 Subject: [PATCH 278/454] support ra2a1 pipe numbering, fix ra2a1 ek led/button. Though usb not enumerated yet, probably due to bsp/clock setup --- hw/bsp/ra/boards/ra2a1_ek/board.h | 4 +- hw/bsp/ra/family.c | 3 + hw/bsp/ra/vector_data.h | 3 + src/portable/renesas/rusb2/dcd_rusb2.c | 80 +++++++++++--------------- 4 files changed, 42 insertions(+), 48 deletions(-) diff --git a/hw/bsp/ra/boards/ra2a1_ek/board.h b/hw/bsp/ra/boards/ra2a1_ek/board.h index c132387bc..1c2b666d2 100644 --- a/hw/bsp/ra/boards/ra2a1_ek/board.h +++ b/hw/bsp/ra/boards/ra2a1_ek/board.h @@ -31,10 +31,10 @@ extern "C" { #endif -#define LED1 BSP_IO_PORT_01_PIN_06 +#define LED1 BSP_IO_PORT_02_PIN_05 #define LED_STATE_ON 1 -#define SW1 BSP_IO_PORT_01_PIN_05 +#define SW1 BSP_IO_PORT_02_PIN_06 #define BUTTON_STATE_ACTIVE 0 static const ioport_pin_cfg_t board_pin_cfg[] = { diff --git a/hw/bsp/ra/family.c b/hw/bsp/ra/family.c index 16332be17..db8988a36 100644 --- a/hw/bsp/ra/family.c +++ b/hw/bsp/ra/family.c @@ -64,8 +64,11 @@ BSP_DONT_REMOVE BSP_PLACE_IN_SECTION(BSP_SECTION_APPLICATION_VECTORS) const fsp_vector_t g_vector_table[BSP_ICU_VECTOR_MAX_ENTRIES] = { [0] = usbfs_interrupt_handler, /* USBFS INT (USBFS interrupt) */ [1] = usbfs_resume_handler, /* USBFS RESUME (USBFS resume interrupt) */ + +#ifndef BSP_MCU_GROUP_RA2A1 [2] = usbfs_d0fifo_handler, /* USBFS FIFO 0 (DMA transfer request 0) */ [3] = usbfs_d1fifo_handler, /* USBFS FIFO 1 (DMA transfer request 1) */ +#endif #ifdef BOARD_HAS_USB_HIGHSPEED [4] = usbhs_interrupt_handler, /* USBHS INT (USBHS interrupt) */ diff --git a/hw/bsp/ra/vector_data.h b/hw/bsp/ra/vector_data.h index ca667faa3..2b3b7d837 100644 --- a/hw/bsp/ra/vector_data.h +++ b/hw/bsp/ra/vector_data.h @@ -9,8 +9,11 @@ extern "C" { /* ISR prototypes */ void usbfs_interrupt_handler(void); void usbfs_resume_handler(void); + +#ifndef BSP_MCU_GROUP_RA2A1 void usbfs_d0fifo_handler(void); void usbfs_d1fifo_handler(void); +#endif #ifdef BOARD_HAS_USB_HIGHSPEED void usbhs_interrupt_handler(void); diff --git a/src/portable/renesas/rusb2/dcd_rusb2.c b/src/portable/renesas/rusb2/dcd_rusb2.c index 0d53b7a7b..0fcf1b688 100644 --- a/src/portable/renesas/rusb2/dcd_rusb2.c +++ b/src/portable/renesas/rusb2/dcd_rusb2.c @@ -89,6 +89,10 @@ static dcd_data_t _dcd; // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ +enum { + PIPE_COUNT = 10, +}; + // Transfer conditions specifiable for each pipe for most MCUs // - Pipe 0: Control transfer with 64-byte single buffer // - Pipes 1 and 2: Bulk or ISO @@ -97,44 +101,33 @@ static dcd_data_t _dcd; // // Note: for small mcu such as // - RA2A1: only pipe 4-7 are available, and no support for ISO - -enum { - PIPE_LAST_ISO = 2, - PIPE_LAST_BULK = 5, - PIPE_LAST_INTERRUPT = 9, - PIPE_COUNT = 10, -}; - static unsigned find_pipe(unsigned xfer_type) { - switch (xfer_type) { - case TUSB_XFER_ISOCHRONOUS: - for (int i = PIPE_LAST_ISO; i > 0; i--) { - if (0 == _dcd.pipe[i].ep) return i; - } - break; + #if defined(BSP_MCU_GROUP_RA2A1) + const uint8_t pipe_idx_arr[4][2] = { + { 0, 0 }, // Control + { 0, 0 }, // Isochronous not supported + { 4, 5 }, // Bulk + { 6, 7 }, // Interrupt + }; + #else + const uint8_t pipe_idx_arr[4][2] = { + { 0, 0 }, // Control + { 1, 2 }, // Isochronous + { 1, 5 }, // Bulk + { 6, 9 }, // Interrupt + }; + #endif - case TUSB_XFER_BULK: - // find backward since only pipe 1, 2 support ISO - for (int i = PIPE_LAST_BULK; i > 0; i--) { - if (0 == _dcd.pipe[i].ep) return i; - } - break; - - case TUSB_XFER_INTERRUPT: - for(int i = PIPE_LAST_INTERRUPT; i > PIPE_LAST_BULK; i--) { - if (0 == _dcd.pipe[i].ep) return i; - } - break; - - default: - /* No support for control transfer */ - break; + // find backward since only pipe 1, 2 support ISO + const uint8_t* idx = pipe_idx_arr[xfer_type]; + for (int i = idx[1]; i >= idx[0]; i--) { + if (0 == _dcd.pipe[i].ep) return i; } + return 0; } -static volatile uint16_t* get_pipectr(rusb2_reg_t *rusb, unsigned num) -{ +static volatile uint16_t* get_pipectr(rusb2_reg_t *rusb, unsigned num) { if (num) { return (volatile uint16_t*)&(rusb->PIPE_CTR[num - 1]); } else { @@ -142,8 +135,7 @@ static volatile uint16_t* get_pipectr(rusb2_reg_t *rusb, unsigned num) } } -static volatile reg_pipetre_t* get_pipetre(rusb2_reg_t *rusb, unsigned num) -{ +static volatile reg_pipetre_t* get_pipetre(rusb2_reg_t *rusb, unsigned num) { volatile reg_pipetre_t* tre = NULL; if ((1 <= num) && (num <= 5)) { tre = (volatile reg_pipetre_t*)&(rusb->PIPE_TR[num - 1].E); @@ -151,8 +143,7 @@ static volatile reg_pipetre_t* get_pipetre(rusb2_reg_t *rusb, unsigned num) return tre; } -static volatile uint16_t* ep_addr_to_pipectr(uint8_t rhport, unsigned ep_addr) -{ +static volatile uint16_t* ep_addr_to_pipectr(uint8_t rhport, unsigned ep_addr) { rusb2_reg_t *rusb = RUSB2_REG(rhport); const unsigned epn = tu_edpt_number(ep_addr); @@ -165,19 +156,16 @@ static volatile uint16_t* ep_addr_to_pipectr(uint8_t rhport, unsigned ep_addr) } } -static uint16_t edpt0_max_packet_size(rusb2_reg_t* rusb) -{ +static uint16_t edpt0_max_packet_size(rusb2_reg_t* rusb) { return rusb->DCPMAXP_b.MXPS; } -static uint16_t edpt_max_packet_size(rusb2_reg_t *rusb, unsigned num) -{ +static uint16_t edpt_max_packet_size(rusb2_reg_t *rusb, unsigned num) { rusb->PIPESEL = num; return rusb->PIPEMAXP; } -static inline void pipe_wait_for_ready(rusb2_reg_t * rusb, unsigned num) -{ +static inline void pipe_wait_for_ready(rusb2_reg_t * rusb, unsigned num) { while ( rusb->D0FIFOSEL_b.CURPIPE != num ) {} while ( !rusb->D0FIFOCTR_b.FRDY ) {} } @@ -1026,10 +1014,10 @@ void dcd_int_handler(uint8_t rhport) /* clear active bits (don't write 0 to already cleared bits according to the HW manual) */ rusb->BRDYSTS = ~s; - for (unsigned pipe = 0; pipe < PIPE_COUNT; ++pipe) { - if (tu_bit_test(s, pipe)) { - process_pipe_brdy(rhport, pipe); - s = tu_bit_clear(s, pipe); + for (unsigned p = 0; p < PIPE_COUNT; ++p) { + if (tu_bit_test(s, p)) { + process_pipe_brdy(rhport, p); + s = tu_bit_clear(s, p); } } } From daf1c7303ce390407ab876a5230bc2520cbfd573 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 10 Apr 2024 20:09:11 +0700 Subject: [PATCH 279/454] fix mask typo for brdysts when using pipe9 --- src/portable/renesas/rusb2/dcd_rusb2.c | 37 ++++++++++---------------- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/src/portable/renesas/rusb2/dcd_rusb2.c b/src/portable/renesas/rusb2/dcd_rusb2.c index 0fcf1b688..a65d056cf 100644 --- a/src/portable/renesas/rusb2/dcd_rusb2.c +++ b/src/portable/renesas/rusb2/dcd_rusb2.c @@ -57,29 +57,22 @@ //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ +enum { + PIPE_COUNT = 10, +}; -/* Start of definition of packed structs (used by the CCRX toolchain) */ -TU_ATTR_PACKED_BEGIN -TU_ATTR_BIT_FIELD_ORDER_BEGIN - -typedef struct TU_ATTR_PACKED -{ +typedef struct { 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 */ - struct { - uint32_t ep : 8; /* an assigned endpoint address */ - uint32_t ff : 1; /* `buf` is TU_FUFO or POD */ - uint32_t : 0; - }; -} pipe_state_t; -TU_ATTR_PACKED_END // End of definition of packed structs (used by the CCRX toolchain) -TU_ATTR_BIT_FIELD_ORDER_END + uint8_t ep; /* an assigned endpoint address */ + uint8_t ff; /* `buf` is TU_FUFO or POD */ +} pipe_state_t; typedef struct { - pipe_state_t pipe[10]; + pipe_state_t pipe[PIPE_COUNT]; uint8_t ep[2][16]; /* a lookup table for a pipe index from an endpoint address */ } dcd_data_t; @@ -89,9 +82,6 @@ static dcd_data_t _dcd; // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ -enum { - PIPE_COUNT = 10, -}; // Transfer conditions specifiable for each pipe for most MCUs // - Pipe 0: Control transfer with 64-byte single buffer @@ -119,8 +109,10 @@ static unsigned find_pipe(unsigned xfer_type) { #endif // find backward since only pipe 1, 2 support ISO - const uint8_t* idx = pipe_idx_arr[xfer_type]; - for (int i = idx[1]; i >= idx[0]; i--) { + const uint8_t idx_first = pipe_idx_arr[xfer_type][0]; + const uint8_t idx_last = pipe_idx_arr[xfer_type][1]; + + for (int i = idx_last; i >= idx_first; i--) { if (0 == _dcd.pipe[i].ep) return i; } @@ -823,7 +815,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) } rusb->PIPECFG = cfg; - rusb->BRDYSTS = 0x1FFu ^ TU_BIT(num); + rusb->BRDYSTS = 0x3FFu ^ TU_BIT(num); rusb->BRDYENB |= TU_BIT(num); if (dir || (xfer != TUSB_XFER_BULK)) { @@ -1010,14 +1002,13 @@ void dcd_int_handler(uint8_t rhport) // Buffer ready if ( is0 & RUSB2_INTSTS0_BRDY_Msk ) { const unsigned m = rusb->BRDYENB; - unsigned s = rusb->BRDYSTS & m; + const unsigned s = rusb->BRDYSTS & m; /* clear active bits (don't write 0 to already cleared bits according to the HW manual) */ rusb->BRDYSTS = ~s; for (unsigned p = 0; p < PIPE_COUNT; ++p) { if (tu_bit_test(s, p)) { process_pipe_brdy(rhport, p); - s = tu_bit_clear(s, p); } } } From 03cfe90f3ef44c2f4e46509701dfbad5af9991e5 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Wed, 10 Apr 2024 22:21:53 +0200 Subject: [PATCH 280/454] flush fifo in dcd_edpt_close_all() --- src/portable/synopsys/dwc2/dcd_dwc2.c | 33 +++++++++++++++------------ 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index d01d9645b..40e59136d 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -101,6 +101,19 @@ static uint16_t _allocated_fifo_words_tx; // TX FIFO size in words (IN EPs) // SOF enabling flag - required for SOF to not get disabled in ISR when SOF was enabled by static bool _sof_en; +static inline void fifo_flush(uint8_t rhport) +{ + dwc2_regs_t* dwc2 = DWC2_REG(rhport); + + // flush all TX fifo and wait for it cleared + dwc2->grstctl = GRSTCTL_TXFFLSH | (0x10u << GRSTCTL_TXFNUM_Pos); + while (dwc2->grstctl & GRSTCTL_TXFFLSH_Msk) {} + + // flush RX fifo and wait for it cleared + dwc2->grstctl = GRSTCTL_RXFFLSH; + while (dwc2->grstctl & GRSTCTL_RXFFLSH_Msk) {} +} + // 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) + @@ -270,13 +283,7 @@ static void bus_reset(uint8_t rhport) { dwc2->epout[n].doepctl |= DOEPCTL_SNAK; } - // flush all TX fifo and wait for it cleared - dwc2->grstctl = GRSTCTL_TXFFLSH | (0x10u << GRSTCTL_TXFNUM_Pos); - while (dwc2->grstctl & GRSTCTL_TXFFLSH_Msk) {} - - // flush RX fifo and wait for it cleared - dwc2->grstctl = GRSTCTL_RXFFLSH; - while (dwc2->grstctl & GRSTCTL_RXFFLSH_Msk) {} + fifo_flush(rhport); // 2. Set up interrupt mask dwc2->daintmsk = TU_BIT(DAINTMSK_OEPM_Pos) | TU_BIT(DAINTMSK_IEPM_Pos); @@ -584,13 +591,7 @@ void dcd_init(uint8_t rhport) { // (non zero-length packet), send STALL back and discard. dwc2->dcfg |= DCFG_NZLSOHSK; - // flush all TX fifo and wait for it cleared - dwc2->grstctl = GRSTCTL_TXFFLSH | (0x10u << GRSTCTL_TXFNUM_Pos); - while (dwc2->grstctl & GRSTCTL_TXFFLSH_Msk) {} - - // flush RX fifo and wait for it cleared - dwc2->grstctl = GRSTCTL_RXFFLSH; - while (dwc2->grstctl & GRSTCTL_RXFFLSH_Msk) {} + fifo_flush(rhport); // Clear all interrupts uint32_t int_mask = dwc2->gintsts; @@ -708,8 +709,12 @@ 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(rhport); } bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { From 3991ff34f11994e09f77d07e4d1b2fe4810cc01d Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 11 Apr 2024 10:50:26 +0700 Subject: [PATCH 281/454] use pull_request_target for labeler --- .github/workflows/labeler.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index 5b22d977e..4d61fd350 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -3,7 +3,7 @@ name: Labeler on: issues: types: [opened] - pull_request: + pull_request_target: types: [opened] jobs: @@ -25,9 +25,9 @@ jobs: if (context.eventName === 'issues') { username = context.payload.issue.user.login; issueOrPrNumber = context.payload.issue.number; - } else if (context.eventName === 'pull_request') { - username = context.payload.pull_request.user.login; - issueOrPrNumber = context.payload.pull_request.number; + } else if (context.eventName === 'pull_request_target') { + username = context.payload.pull_request_target.user.login; + issueOrPrNumber = context.payload.pull_request_target.number; } // Check if an Adafruit member From 79cbe93fcff83a5764acd2427af410b896434d5f Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 11 Apr 2024 11:02:54 +0700 Subject: [PATCH 282/454] separate flush tx/rx fifo --- src/portable/synopsys/dwc2/dcd_dwc2.c | 36 +++++++++++++-------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 40e59136d..830a1ccd0 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -101,19 +101,6 @@ static uint16_t _allocated_fifo_words_tx; // TX FIFO size in words (IN EPs) // SOF enabling flag - required for SOF to not get disabled in ISR when SOF was enabled by static bool _sof_en; -static inline void fifo_flush(uint8_t rhport) -{ - dwc2_regs_t* dwc2 = DWC2_REG(rhport); - - // flush all TX fifo and wait for it cleared - dwc2->grstctl = GRSTCTL_TXFFLSH | (0x10u << GRSTCTL_TXFNUM_Pos); - while (dwc2->grstctl & GRSTCTL_TXFFLSH_Msk) {} - - // flush RX fifo and wait for it cleared - dwc2->grstctl = GRSTCTL_RXFFLSH; - while (dwc2->grstctl & GRSTCTL_RXFFLSH_Msk) {} -} - // 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) + @@ -125,6 +112,17 @@ 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; } +TU_ATTR_ALWAYS_INLINE static inline void fifo_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) { + // 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) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); uint8_t const ep_count = _dwc2_controller[rhport].ep_count; @@ -238,8 +236,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. - dwc2->grstctl = ((epnum << GRSTCTL_TXFNUM_Pos) | GRSTCTL_TXFFLSH); - while ((dwc2->grstctl & GRSTCTL_TXFFLSH_Msk) != 0) {} + fifo_flush_tx(dwc2, epnum); } else { dwc2_epout_t* epout = dwc2->epout; @@ -283,7 +280,8 @@ static void bus_reset(uint8_t rhport) { dwc2->epout[n].doepctl |= DOEPCTL_SNAK; } - fifo_flush(rhport); + fifo_flush_tx(dwc2, 0x10); // all tx fifo + fifo_flush_rx(dwc2); // 2. Set up interrupt mask dwc2->daintmsk = TU_BIT(DAINTMSK_OEPM_Pos) | TU_BIT(DAINTMSK_IEPM_Pos); @@ -591,7 +589,8 @@ void dcd_init(uint8_t rhport) { // (non zero-length packet), send STALL back and discard. dwc2->dcfg |= DCFG_NZLSOHSK; - fifo_flush(rhport); + fifo_flush_tx(dwc2, 0x10); // all tx fifo + fifo_flush_rx(dwc2); // Clear all interrupts uint32_t int_mask = dwc2->gintsts; @@ -714,7 +713,8 @@ void dcd_edpt_close_all(uint8_t rhport) { // reset allocated fifo IN _allocated_fifo_words_tx = 16; - fifo_flush(rhport); + fifo_flush_tx(dwc2, 0x10); // all tx fifo + fifo_flush_rx(dwc2); } bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { From b992b6d7a6f90cd96f7d53383755dc17e393f00e Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 11 Apr 2024 12:06:13 +0700 Subject: [PATCH 283/454] apply find_pipe() and forloop for hcd --- src/portable/renesas/rusb2/dcd_rusb2.c | 1 - src/portable/renesas/rusb2/hcd_rusb2.c | 75 ++++++++++---------------- 2 files changed, 29 insertions(+), 47 deletions(-) diff --git a/src/portable/renesas/rusb2/dcd_rusb2.c b/src/portable/renesas/rusb2/dcd_rusb2.c index a65d056cf..f9523191a 100644 --- a/src/portable/renesas/rusb2/dcd_rusb2.c +++ b/src/portable/renesas/rusb2/dcd_rusb2.c @@ -1005,7 +1005,6 @@ void dcd_int_handler(uint8_t rhport) const unsigned s = rusb->BRDYSTS & m; /* clear active bits (don't write 0 to already cleared bits according to the HW manual) */ rusb->BRDYSTS = ~s; - for (unsigned p = 0; p < PIPE_COUNT; ++p) { if (tu_bit_test(s, p)) { process_pipe_brdy(rhport, p); diff --git a/src/portable/renesas/rusb2/hcd_rusb2.c b/src/portable/renesas/rusb2/hcd_rusb2.c index bf95be707..1356b696f 100644 --- a/src/portable/renesas/rusb2/hcd_rusb2.c +++ b/src/portable/renesas/rusb2/hcd_rusb2.c @@ -45,6 +45,9 @@ //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ +enum { + PIPE_COUNT = 10, +}; TU_ATTR_PACKED_BEGIN TU_ATTR_BIT_FIELD_ORDER_BEGIN @@ -75,7 +78,7 @@ TU_ATTR_BIT_FIELD_ORDER_END typedef struct { bool need_reset; /* The device has not been reset after connection. */ - pipe_state_t pipe[10]; + pipe_state_t pipe[PIPE_COUNT]; uint8_t ep[4][2][15]; /* a lookup table for a pipe index from an endpoint address */ uint8_t ctl_mps[5]; /* EP0 max packet size for each device */ } hcd_data_t; @@ -86,46 +89,30 @@ typedef struct static hcd_data_t _hcd; // TODO merged with DCD -// Transfer conditions specifiable for each pipe: +// Transfer conditions specifiable for each pipe for most MCUs // - Pipe 0: Control transfer with 64-byte single buffer -// - Pipes 1 and 2: Bulk isochronous transfer continuous transfer mode with programmable buffer size up -// to 2 KB and optional double buffer -// - Pipes 3 to 5: Bulk transfer continuous transfer mode with programmable buffer size up to 2 KB and -// optional double buffer -// - Pipes 6 to 9: Interrupt transfer with 64-byte single buffer -enum { - PIPE_1ST_BULK = 3, - PIPE_1ST_INTERRUPT = 6, - PIPE_COUNT = 10, -}; +// - Pipes 1 and 2: Bulk or ISO +// - Pipes 3 to 5: Bulk +// - Pipes 6 to 9: Interrupt +// +// Note: for small mcu such as +// - RA2A1: only pipe 4-7 are available, and no support for ISO +static unsigned find_pipe(unsigned xfer_type) { + const uint8_t pipe_idx_arr[4][2] = { + { 0, 0 }, // Control + { 1, 2 }, // Isochronous + { 1, 5 }, // Bulk + { 6, 9 }, // Interrupt + }; -static unsigned find_pipe(unsigned xfer) { - switch ( xfer ) { - case TUSB_XFER_ISOCHRONOUS: - for (int i = 1; i < PIPE_1ST_BULK; ++i) { - if ( 0 == _hcd.pipe[i].ep ) return i; - } - break; + // find backward since only pipe 1, 2 support ISO + const uint8_t idx_first = pipe_idx_arr[xfer_type][0]; + const uint8_t idx_last = pipe_idx_arr[xfer_type][1]; - case TUSB_XFER_BULK: - for (int i = PIPE_1ST_BULK; i < PIPE_1ST_INTERRUPT; ++i) { - if ( 0 == _hcd.pipe[i].ep ) return i; - } - for (int i = 1; i < PIPE_1ST_BULK; ++i) { - if ( 0 == _hcd.pipe[i].ep ) return i; - } - break; - - case TUSB_XFER_INTERRUPT: - for (int i = PIPE_1ST_INTERRUPT; i < PIPE_COUNT; ++i) { - if ( 0 == _hcd.pipe[i].ep ) return i; - } - break; - - default: - /* No support for control transfer */ - break; + for (int i = idx_last; i >= idx_first; i--) { + if (0 == _hcd.pipe[i].ep) return i; } + return 0; } @@ -718,7 +705,7 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const } rusb->PIPECFG = cfg; - rusb->BRDYSTS = 0x1FFu ^ TU_BIT(num); + rusb->BRDYSTS = 0x3FFu ^ TU_BIT(num); rusb->NRDYENB |= TU_BIT(num); rusb->BRDYENB |= TU_BIT(num); @@ -846,14 +833,10 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { unsigned s = rusb->BRDYSTS & m; /* clear active bits (don't write 0 to already cleared bits according to the HW manual) */ rusb->BRDYSTS = ~s; - while (s) { -#if defined(__CCRX__) - const unsigned num = Mod37BitPosition[(-s & s) % 37]; -#else - const unsigned num = __builtin_ctz(s); -#endif - process_pipe_brdy(rhport, num); - s &= ~TU_BIT(num); + for (unsigned p = 0; p < PIPE_COUNT; ++p) { + if (tu_bit_test(s, p)) { + process_pipe_brdy(rhport, p); + } } } } From 535571c3d278efbbeebdc531c36ce1f492ea4d05 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 11 Apr 2024 19:25:02 +0700 Subject: [PATCH 284/454] - remove redundant call of pcd_set_ep_rx_cnt() - minor code format --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 149 +++++++++--------- 1 file changed, 72 insertions(+), 77 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index c11a8c625..56c9bc84b 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -216,22 +216,19 @@ 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 - { + for (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 (uint32_t i = 0; i < 200; i++) // should be a few us - { + for (uint32_t i = 0; i < 200; i++) { // should be a few us asm("NOP"); } 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 - { + for (uint32_t i = 0; i < 200; i++) { // should be a few us asm("NOP"); } USB->CNTR = 0; // Enable USB @@ -251,8 +248,9 @@ void dcd_init(uint8_t rhport) dcd_handle_bus_reset(); // Enable pull-up if supported - if (dcd_connect) + if (dcd_connect) { dcd_connect(rhport); + } } // Define only on MCU with internal pull-up. BSP can define on MCU without internal PU. @@ -441,21 +439,23 @@ void dcd_remote_wakeup(uint8_t rhport) 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, +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 +}; - .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 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) { @@ -503,8 +503,9 @@ static void dcd_ep_ctr_tx_handler(uint32_t wIstr) xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); /* Ignore spurious int */ - if (xfer->in_complete) + if (xfer->in_complete) { return; + } xfer->in_complete = true; if ((wEPRegVal & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS) { @@ -515,11 +516,9 @@ static void dcd_ep_ctr_tx_handler(uint32_t wIstr) } } - if ((xfer->total_len != xfer->queued_len)) /* TX not complete */ - { + if ((xfer->total_len != xfer->queued_len)) { dcd_transmit_packet(xfer, EPindex); - } else /* TX Complete */ - { + } else { dcd_event_xfer_complete(0, ep_addr, xfer->total_len, XFER_RESULT_SUCCESS, true); } } @@ -561,12 +560,11 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) return; } - if ((ep_addr == 0U) && ((wEPRegVal & USB_EP_SETUP) != 0U)) /* Setup packet */ - { + if ((ep_addr == 0U) && ((wEPRegVal & USB_EP_SETUP) != 0U)) { + /* Setup packet */ uint32_t count = pcd_get_ep_rx_cnt(USB, EPindex); - /* Get SETUP Packet*/ - if (count == 8) // Setup packet should always be 8 bytes. If not, ignore it, and try again. - { + // 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) pcd_set_ep_rx_status(USB, 0u, USB_EP_RX_NAK); pcd_set_ep_tx_status(USB, 0u, USB_EP_TX_NAK); @@ -615,16 +613,14 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) } if ((count < xfer->max_packet_size) || (xfer->queued_len == xfer->total_len)) { - /* RX COMPLETE */ + // all bytes received or short packet dcd_event_xfer_complete(0, ep_addr, xfer->queued_len, XFER_RESULT_SUCCESS, true); - // Though the host could still send, we don't know. - // Does the bulk pipe need to be reset to valid to allow for a ZLP? } 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)) { + if ((wEPRegVal & USB_EP_TYPE_MASK) != USB_EP_ISOCHRONOUS) { uint16_t remaining = xfer->total_len - xfer->queued_len; - uint16_t cnt = remaining >= xfer->max_packet_size ? xfer->max_packet_size : remaining; + uint16_t cnt = tu_min16(remaining, xfer->max_packet_size); pcd_set_ep_rx_cnt(USB, EPindex, cnt); pcd_set_ep_rx_cnt(USB, EPindex, remaining); } @@ -734,7 +730,9 @@ 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) { + 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 @@ -781,13 +779,16 @@ static uint8_t dcd_ep_alloc(uint8_t ep_addr, uint8_t ep_type) for (uint8_t i = 0; i < STFSDEV_EP_COUNT; i++) { // Check if already allocated - if (ep_alloc_status[i].allocated[dir] && ep_alloc_status[i].ep_type == ep_type && ep_alloc_status[i].ep_num == epnum) { + if (ep_alloc_status[i].allocated[dir] && + ep_alloc_status[i].ep_type == ep_type && + ep_alloc_status[i].ep_num == epnum) { return i; } // If EP of current direction is not allocated // Except for ISO endpoint, both direction should be free - if (!ep_alloc_status[i].allocated[dir] && (ep_type != TUSB_XFER_ISOCHRONOUS || !ep_alloc_status[i].allocated[dir ^ 1])) { + if (!ep_alloc_status[i].allocated[dir] && + (ep_type != TUSB_XFER_ISOCHRONOUS || !ep_alloc_status[i].allocated[dir ^ 1])) { // Check if EP number is the same if (ep_alloc_status[i].ep_num == 0xFF || ep_alloc_status[i].ep_num == epnum) { // One EP pair has to be the same type @@ -812,8 +813,9 @@ 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 *p_endpoint_desc) { (void)rhport; - uint8_t const ep_idx = dcd_ep_alloc(p_endpoint_desc->bEndpointAddress, p_endpoint_desc->bmAttributes.xfer); - uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); + 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 dir = tu_edpt_dir(ep_addr); const uint16_t packet_size = tu_edpt_packet_size(p_endpoint_desc); const uint16_t buffer_size = pcd_aligned_buffer_size(packet_size); uint16_t pma_addr; @@ -822,28 +824,26 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *p_endpoint_desc) TU_ASSERT(ep_idx < STFSDEV_EP_COUNT); TU_ASSERT(buffer_size <= 64); - // ISO endpoint should use alloc / active functions - TU_ASSERT(p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS); - // Set type switch (p_endpoint_desc->bmAttributes.xfer) { - case TUSB_XFER_CONTROL: - wType = USB_EP_CONTROL; - break; - case TUSB_XFER_BULK: - wType = USB_EP_CONTROL; - break; + case TUSB_XFER_CONTROL: + wType = USB_EP_CONTROL; + break; + case TUSB_XFER_BULK: + wType = USB_EP_CONTROL; + break; - case TUSB_XFER_INTERRUPT: - wType = USB_EP_INTERRUPT; - break; + case TUSB_XFER_INTERRUPT: + wType = USB_EP_INTERRUPT; + break; - default: - TU_ASSERT(false); + default: + // Note: ISO endpoint should use alloc / active functions + TU_ASSERT(false); } pcd_set_eptype(USB, ep_idx, wType); - pcd_set_ep_address(USB, ep_idx, tu_edpt_number(p_endpoint_desc->bEndpointAddress)); + 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); @@ -852,16 +852,14 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *p_endpoint_desc) pcd_set_ep_tx_address(USB, ep_idx, pma_addr); pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_NAK); pcd_clear_tx_dtog(USB, ep_idx); - } - - if (dir == TUSB_DIR_OUT) { + } else { pcd_set_ep_rx_address(USB, ep_idx, pma_addr); pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_NAK); pcd_clear_rx_dtog(USB, ep_idx); } - xfer_ctl_ptr(p_endpoint_desc->bEndpointAddress)->max_packet_size = packet_size; - xfer_ctl_ptr(p_endpoint_desc->bEndpointAddress)->ep_idx = ep_idx; + xfer_ctl_ptr(ep_addr)->max_packet_size = packet_size; + xfer_ctl_ptr(ep_addr)->ep_idx = ep_idx; return true; } @@ -898,8 +896,6 @@ bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet { (void)rhport; - TU_ASSERT(largest_packet_size < 1024); - 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); @@ -925,14 +921,15 @@ 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 *p_endpoint_desc) { (void)rhport; - uint8_t const ep_idx = xfer_ctl_ptr(p_endpoint_desc->bEndpointAddress)->ep_idx; - uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); + 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); pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_DIS); pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_DIS); - pcd_set_ep_address(USB, ep_idx, tu_edpt_number(p_endpoint_desc->bEndpointAddress)); + 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); @@ -943,7 +940,7 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *p_endpoin pcd_tx_dtog(USB, ep_idx); } - xfer_ctl_ptr(p_endpoint_desc->bEndpointAddress)->max_packet_size = packet_size; + xfer_ctl_ptr(ep_addr)->max_packet_size = packet_size; return true; } @@ -953,9 +950,7 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *p_endpoin 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) // max packet size for FS transfer - { + if (len > xfer->max_packet_size) { len = xfer->max_packet_size; } @@ -996,14 +991,16 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr) uint8_t const ep_idx = xfer->ep_idx; uint8_t const dir = tu_edpt_dir(ep_addr); - if (dir == TUSB_DIR_OUT) { + 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 = xfer->total_len > xfer->max_packet_size ? xfer->max_packet_size : xfer->total_len; + 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) { @@ -1014,10 +1011,8 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr) } pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_VALID); - } else // IN - { - dcd_transmit_packet(xfer, ep_idx); } + return true; } @@ -1052,9 +1047,9 @@ 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); - if (dir == TUSB_DIR_IN) { // IN + if (dir == TUSB_DIR_IN) { pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_STALL); - } else { // OUT + } else { pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_STALL); } } From 0f775630c7468b804fad7e3350b37430b6fb0a2d Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 11 Apr 2024 20:53:44 +0700 Subject: [PATCH 285/454] rename, invert logic for iso_in_sending. Also limit its usage to ISO endpoint --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 23 +++++++++++-------- 1 file changed, 14 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 56c9bc84b..493e634c7 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -152,7 +152,7 @@ typedef struct { uint16_t queued_len; uint16_t max_packet_size; uint8_t ep_idx; // index for USB_EPnR register - bool in_complete; // Workaround for ISO IN EP doesn't have interrupt mask + bool iso_in_sending; // Workaround for ISO IN EP doesn't have interrupt mask } xfer_ctl_t; // EP allocator @@ -502,13 +502,15 @@ static void dcd_ep_ctr_tx_handler(uint32_t wIstr) xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); - /* Ignore spurious int */ - if (xfer->in_complete) { - return; - } - xfer->in_complete = true; - if ((wEPRegVal & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS) { + // 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) + if (!xfer->iso_in_sending) { + return; + } + xfer->iso_in_sending = false; + if (wEPRegVal & USB_EP_DTOG_TX) { pcd_set_ep_tx_dbuf0_cnt(USB, EPindex, 0); } else { @@ -955,9 +957,10 @@ 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; - if ((ep_reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS) { + 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); @@ -979,7 +982,9 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) dcd_int_disable(0); pcd_set_ep_tx_status(USB, ep_ix, USB_EP_TX_VALID); - xfer->in_complete = false; + if (is_iso) { + xfer->iso_in_sending = true; + } dcd_int_enable(0); } From 0ce2452a088bd7f1397a8f55d736e4e0100cb32f Mon Sep 17 00:00:00 2001 From: Clifroy Henry Date: Fri, 30 Dec 2022 19:21:53 -0500 Subject: [PATCH 286/454] Add non-bus-powered MSP430 re-enumeration support. --- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 80 +++++++++++++++++++-- 1 file changed, 74 insertions(+), 6 deletions(-) diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index b4dfda575..60aa23b98 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -131,11 +131,17 @@ void dcd_init (uint8_t rhport) USBVECINT = 0; - // Enable reset and wait for it before continuing. - USBIE |= RSTRIE; - - // Enable pullup. - USBCNF |= PUR_EN; + if(USBPWRCTL & USBBGVBV) // Bus power detected? + { + USBPWRCTL |= VBOFFIE; // Enable bus-power-removed interrupt. + USBIE |= RSTRIE; // Enable reset and wait for it before continuing. + USBCNF |= PUR_EN; // Enable pullup. + } + else + { + USBPWRCTL |= VBONIE; // Enable bus-power-applied interrupt. + USBCNF &= ~USB_EN; // Disable USB module until bus power is detected. + } USBKEYPID = 0; } @@ -618,6 +624,48 @@ static void handle_setup_packet(void) dcd_event_setup_received(0, (uint8_t*) &_setup_packet[0], true); } +static void handle_bus_power_event(void *param) +{ + (void) param; + + osal_task_delay(2); // Bus power settling delay. + + USBKEYPID = USBKEY; + + if(USBPWRCTL & USBBGVBV) // Event caused by application of bus power. + { + USBPWRCTL |= VBOFFIE; // Enable bus-power-removed interrupt. + USBPLLDIVB = USBPLLDIVB; // For some reason the PLL will *NOT* lock unless the divider + // register is re-written. The assumption here is that this + // register was already properly configured during board-level + // initialization. + USBPLLCTL |= (UPLLEN | UPFDEN); // Enable the PLL. + + uint16_t attempts = 0; + + do // Poll the PLL to check for a successful lock. + { + USBPLLIR = 0; + osal_task_delay(1); + attempts++; + } while ((attempts < 10) && (USBPLLIR != 0)); + + if(!USBPLLIR) // A successful lock is indicated by all PLL-related interrupt + { // flags being cleared. + dcd_init(0); // Re-initialize the USB module. + } + } + else // Event caused by removal of bus power. + { + USBPWRCTL |= VBONIE; // Enable bus-power-applied interrupt. + USBPLLCTL &= ~(UPLLEN | UPFDEN); // Disable the PLL. + USBCNF = 0; // Disable the USB module. + dcd_event_bus_signal(0, DCD_EVENT_UNPLUGGED, false); + } + + USBKEYPID = 0; +} + void dcd_int_handler(uint8_t rhport) { (void) rhport; @@ -646,11 +694,32 @@ void dcd_int_handler(uint8_t rhport) switch(curr_vector) { + case USBVECINT_NONE: + break; + case USBVECINT_RSTR: bus_reset(); dcd_event_bus_reset(0, TUSB_SPEED_FULL, true); break; + case USBVECINT_PWR_VBUSOn: + case USBVECINT_PWR_VBUSOff: + USBKEYPID = USBKEY; + // Prevent (possibly) unstable power from generating spurious interrupts. + USBPWRCTL &= ~(VBONIE | VBOFFIE); + USBKEYPID = 0; + + { + dcd_event_t event; + + event.rhport = 0; + event.event_id = USBD_EVENT_FUNC_CALL; + event.func_call.func = handle_bus_power_event; + + dcd_event_handler(&event, true); + } + break; + // Clear the (hardware-enforced) NAK on EP 0 after a SETUP packet // is received. At this point, even though the hardware is no longer // forcing NAKs, the EP0 NAK bits should still be set to avoid @@ -710,7 +779,6 @@ void dcd_int_handler(uint8_t rhport) default: while(true); - break; } } From 87905d30ab8c94999bd69d0ae32f91ebdfef39d3 Mon Sep 17 00:00:00 2001 From: Clifroy Henry Date: Tue, 3 Jan 2023 10:33:49 -0500 Subject: [PATCH 287/454] Increase bus powe stabilization delay. --- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index 60aa23b98..c1bef86fa 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -628,7 +628,7 @@ static void handle_bus_power_event(void *param) { (void) param; - osal_task_delay(2); // Bus power settling delay. + osal_task_delay(5); // Bus power settling delay. USBKEYPID = USBKEY; From 5a9b3eab6f3aa5e9fc71b902bfdbfef1acb29b44 Mon Sep 17 00:00:00 2001 From: Clifroy Henry Date: Tue, 3 Jan 2023 11:58:22 -0500 Subject: [PATCH 288/454] Resolve erroneous data on enumeration. --- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index c1bef86fa..46b7d6458 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -616,11 +616,20 @@ static void handle_setup_packet(void) _setup_packet[i] = setup_buf[i]; } - // Clearing SETUPIFG by reading USBVECINT does not set NAK, so now that we - // have a SETUP packet, force NAKs until tinyusb can handle the SETUP - // packet and prepare for a new xfer. + // Force NAKs until tinyusb can handle the SETUP packet and prepare + // for a new xfer. USBIEPCNT_0 |= NAK; USBOEPCNT_0 |= NAK; + + // Clear SETUPIFG to avoid handling in the USBVECINT switch statement. + // When handled there the NAKs applied to the endpoints above are + // cleared by hardware and the host will receive stale/duplicate data. + // + // Excerpt from MSP430x5xx and MSP430x6xx Family User's Guide: + // + // "...the SETUPIFG is cleared upon reading USBIV. In addition, the NAK on + // input endpoint 0 and output endpoint 0 is also cleared." + USBIFG &= ~SETUPIFG; dcd_event_setup_received(0, (uint8_t*) &_setup_packet[0], true); } From b8b22b929e1bbbbae7c7337972129ae6f7192bc6 Mon Sep 17 00:00:00 2001 From: Clifroy Henry Date: Tue, 3 Jan 2023 15:56:14 -0500 Subject: [PATCH 289/454] Allow re-enumeration on host power cycle. --- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index 46b7d6458..a0d9b3ea5 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -94,7 +94,12 @@ static void bus_reset(void) USBOEPCNT_0 &= ~NAK; USBIEPCNT_0 &= ~NAK; - USBCTL |= FEN; // Enable responding to packets. + // Disable (subsequent) bus reset events from causing a functional + // reset of the USB module. + USBCTL &= ~FRSTE; + + // Enable responding to packets. + USBCTL |= FEN; // Dedicated buffers in hardware for SETUP and EP0, no setup needed. // Now safe to respond to SETUP packets. @@ -334,6 +339,10 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t if(epnum == 0) { + // Enables a bus reset to cause a functional reset of the USB + // module. + USBCTL |= FRSTE; + if(dir == TUSB_DIR_OUT) { // Interrupt will notify us when data was received. From a3286932add7c8142b94160522f19e5544e27c0a Mon Sep 17 00:00:00 2001 From: Clifroy Henry Date: Sat, 8 Jul 2023 17:21:19 -0400 Subject: [PATCH 290/454] Correctly implementing recommended workarounds for erratas USB4 and USB10. --- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 40 ++++++++++++++++----- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index a0d9b3ea5..25c2fb301 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -94,10 +94,6 @@ static void bus_reset(void) USBOEPCNT_0 &= ~NAK; USBIEPCNT_0 &= ~NAK; - // Disable (subsequent) bus reset events from causing a functional - // reset of the USB module. - USBCTL &= ~FRSTE; - // Enable responding to packets. USBCTL |= FEN; @@ -108,6 +104,28 @@ static void bus_reset(void) USBKEYPID = 0; } +// Controls reset behavior of the USB module on receipt of a bus reset event. +// - enable: When true, bus reset events will cause a reset the USB module. +static void enable_functional_reset(const bool enable) +{ + // Check whether or not the USB configuration registers were + // locked prior to this function being called so that, if + // necessary, the lock state can be restored on exit. + bool unlocked = (USBKEYPID == 0xA528) ? true : false; + + if(!unlocked) USBKEYPID = USBKEY; + + if(enable) + { + USBCTL |= FRSTE; + } + else + { + USBCTL &= ~FRSTE; + } + + if(!unlocked) USBKEYPID = 0; +} /*------------------------------------------------------------------*/ /* Controller API @@ -339,10 +357,6 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t if(epnum == 0) { - // Enables a bus reset to cause a functional reset of the USB - // module. - USBCTL |= FRSTE; - if(dir == TUSB_DIR_OUT) { // Interrupt will notify us when data was received. @@ -638,7 +652,11 @@ static void handle_setup_packet(void) // // "...the SETUPIFG is cleared upon reading USBIV. In addition, the NAK on // input endpoint 0 and output endpoint 0 is also cleared." + USBIEPCNF_0 &= ~UBME; // Errata USB10 workaround. + USBOEPCNF_0 &= ~UBME; // Errata USB10 workaround. USBIFG &= ~SETUPIFG; + USBIEPCNF_0 |= UBME; // Errata USB10 workaround. + USBOEPCNF_0 |= UBME; // Errata USB10 workaround. dcd_event_setup_received(0, (uint8_t*) &_setup_packet[0], true); } @@ -661,7 +679,7 @@ static void handle_bus_power_event(void *param) uint16_t attempts = 0; - do // Poll the PLL to check for a successful lock. + do // Poll the PLL, checking for a successful lock. { USBPLLIR = 0; osal_task_delay(1); @@ -694,6 +712,7 @@ void dcd_int_handler(uint8_t rhport) if(setup_status) { + enable_functional_reset(true); handle_setup_packet(); } @@ -716,6 +735,7 @@ void dcd_int_handler(uint8_t rhport) break; case USBVECINT_RSTR: + enable_functional_reset(false); // Errata USB4 workaround. bus_reset(); dcd_event_bus_reset(0, TUSB_SPEED_FULL, true); break; @@ -762,10 +782,12 @@ void dcd_int_handler(uint8_t rhport) break; case USBVECINT_INPUT_ENDPOINT0: + enable_functional_reset(true); transmit_packet(0); break; case USBVECINT_OUTPUT_ENDPOINT0: + enable_functional_reset(true); receive_packet(0); break; From 5d3b0896e1eeb1bd45bcb4f2031c7a571f1a16cb Mon Sep 17 00:00:00 2001 From: Clifroy Henry Date: Sat, 8 Jul 2023 17:36:08 -0400 Subject: [PATCH 291/454] Removed trailing whitespace. --- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index 25c2fb301..870cd725d 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -688,7 +688,7 @@ static void handle_bus_power_event(void *param) if(!USBPLLIR) // A successful lock is indicated by all PLL-related interrupt { // flags being cleared. - dcd_init(0); // Re-initialize the USB module. + dcd_init(0); // Re-initialize the USB module. } } else // Event caused by removal of bus power. From dfef0bc81b1677c2d6bbd148b8a0cea4b64aacec Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 11 Apr 2024 22:00:25 +0200 Subject: [PATCH 292/454] Cleanup --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 493e634c7..c38247c38 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -459,13 +459,9 @@ static const tusb_desc_endpoint_t ep0IN_desc = { static void dcd_handle_bus_reset(void) { - //__IO uint16_t * const epreg = &(EPREG(0)); USB->DADDR = 0u; // disable USB peripheral by clearing the EF flag for (uint32_t i = 0; i < STFSDEV_EP_COUNT; i++) { - // Clear all EPREG (or maybe this is automatic? I'm not sure) - pcd_set_endpoint(USB, i, 0u); - // Clear EP allocation status ep_alloc_status[i].ep_num = 0xFF; ep_alloc_status[i].ep_type = 0xFF; @@ -624,7 +620,6 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) 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); - pcd_set_ep_rx_cnt(USB, EPindex, remaining); } pcd_set_ep_rx_status(USB, EPindex, USB_EP_RX_VALID); } From 049ceda315cb581eba27c31952f82353bb881520 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 11 Apr 2024 22:02:44 +0200 Subject: [PATCH 293/454] Implement dcd_edpt_close_all() --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 14 +++++++++++++- 1 file changed, 13 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 c38247c38..cd6142d3a 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -864,7 +864,19 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *p_endpoint_desc) void dcd_edpt_close_all(uint8_t rhport) { (void)rhport; - // TODO implement dcd_edpt_close_all() + + for (uint32_t i = 1; i < STFSDEV_EP_COUNT; i++) { + // Reset endpoint + pcd_set_endpoint(USB, i, 0); + // Clear EP allocation status + ep_alloc_status[i].ep_num = 0xFF; + ep_alloc_status[i].ep_type = 0xFF; + ep_alloc_status[i].allocated[0] = false; + ep_alloc_status[i].allocated[1] = false; + } + + // Reset PMA allocation + ep_buf_ptr = DCD_STM32_BTABLE_BASE + 8 * MAX_EP_COUNT + 2 * CFG_TUD_ENDPOINT0_SIZE; } /** From 2fef23d0666580088ad6f3c97909b3267d7c8770 Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Fri, 12 Apr 2024 10:57:27 +0700 Subject: [PATCH 294/454] Update labeler.yml --- .github/workflows/labeler.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index 4d61fd350..c3cc59d0d 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -26,8 +26,8 @@ jobs: username = context.payload.issue.user.login; issueOrPrNumber = context.payload.issue.number; } else if (context.eventName === 'pull_request_target') { - username = context.payload.pull_request_target.user.login; - issueOrPrNumber = context.payload.pull_request_target.number; + username = context.payload.pull_request.user.login; + issueOrPrNumber = context.payload.pull_request.number; } // Check if an Adafruit member From abddc850ac8bc1377d8c1785a76bbba22405c5e8 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 11 Apr 2024 21:49:55 +0700 Subject: [PATCH 295/454] add cmake support for msp430 --- .idea/cmake.xml | 12 ++- examples/build_system/cmake/cpu/msp430.cmake | 7 ++ .../cmake/toolchain/msp430_gcc.cmake | 52 ++++++++++++ hw/bsp/family_support.cmake | 15 ++++ .../boards/msp_exp430f5529lp/board.cmake | 9 ++ hw/bsp/msp430/family.cmake | 84 +++++++++++++++++++ hw/bsp/msp430/family.mk | 9 +- 7 files changed, 180 insertions(+), 8 deletions(-) create mode 100644 examples/build_system/cmake/cpu/msp430.cmake create mode 100644 examples/build_system/cmake/toolchain/msp430_gcc.cmake create mode 100644 hw/bsp/msp430/boards/msp_exp430f5529lp/board.cmake create mode 100644 hw/bsp/msp430/family.cmake diff --git a/.idea/cmake.xml b/.idea/cmake.xml index ebc6a0570..c361e237d 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -2,8 +2,9 @@ - - + + + @@ -44,7 +45,7 @@ - + @@ -57,8 +58,10 @@ - + + + @@ -82,6 +85,7 @@ + \ No newline at end of file diff --git a/examples/build_system/cmake/cpu/msp430.cmake b/examples/build_system/cmake/cpu/msp430.cmake new file mode 100644 index 000000000..b4b47a2e8 --- /dev/null +++ b/examples/build_system/cmake/cpu/msp430.cmake @@ -0,0 +1,7 @@ +if (TOOLCHAIN STREQUAL "gcc") + set(FREERTOS_PORT GCC_MSP430F449 CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "iar") + set(FREERTOS_PORT IAR_MSP430 CACHE INTERNAL "") + +endif () diff --git a/examples/build_system/cmake/toolchain/msp430_gcc.cmake b/examples/build_system/cmake/toolchain/msp430_gcc.cmake new file mode 100644 index 000000000..6291ce5a4 --- /dev/null +++ b/examples/build_system/cmake/toolchain/msp430_gcc.cmake @@ -0,0 +1,52 @@ +set(CMAKE_SYSTEM_NAME Generic) + +if (NOT DEFINED CMAKE_C_COMPILER) + set(CMAKE_C_COMPILER "msp430-elf-gcc") +endif () + +if (NOT DEFINED CMAKE_CXX_COMPILER) + set(CMAKE_CXX_COMPILER "msp430-elf-g++") +endif () + +set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) + +set(CMAKE_SIZE "msp430-elf-size" CACHE FILEPATH "") +set(CMAKE_OBJCOPY "msp430-elf-objcopy" CACHE FILEPATH "") +set(CMAKE_OBJDUMP "msp430-elf-objdump" CACHE FILEPATH "") + +set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE) + +# Look for includes and libraries only in the target system prefix. +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + +# pass TOOLCHAIN_CPU to +set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES CMAKE_SYSTEM_PROCESSOR) + +include(${CMAKE_CURRENT_LIST_DIR}/../cpu/${CMAKE_SYSTEM_PROCESSOR}.cmake) + +# enable all possible warnings for building examples +list(APPEND TOOLCHAIN_COMMON_FLAGS + -fdata-sections + -ffunction-sections + -fsingle-precision-constant + -fno-strict-aliasing + ) + +list(APPEND TOOLCHAIN_EXE_LINKER_FLAGS + -Wl,--print-memory-usage + -Wl,--gc-sections + -Wl,--cref + ) + +include(${CMAKE_CURRENT_LIST_DIR}/set_flags.cmake) + +# try_compile is cmake test compiling its own example, +# pass -nostdlib to skip stdlib linking +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") +endif () diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index 4ccd6e4f2..d4f355e0c 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -460,6 +460,21 @@ function(family_flash_dfu_util TARGET OPTION) ) endfunction() +function(family_flash_msp430flasher TARGET) + if (NOT DEFINED MSP430Flasher) + set(MSP430FLASHER MSP430Flasher) + endif () + + # set LD_LIBRARY_PATH to find libmsp430.so (directory containing MSP430Flasher) + find_program(MSP430FLASHER_PATH MSP430Flasher) + get_filename_component(MSP430FLASHER_PARENT_DIR "${MSP430FLASHER_PATH}" DIRECTORY) + add_custom_target(${TARGET}-msp430flasher + DEPENDS ${TARGET} + COMMAND ${CMAKE_COMMAND} -E env LD_LIBRARY_PATH=${MSP430FLASHER_PARENT_DIR} + ${MSP430FLASHER} -w $/${TARGET}.hex -z [VCC] + ) +endfunction() + #---------------------------------- # Family specific #---------------------------------- diff --git a/hw/bsp/msp430/boards/msp_exp430f5529lp/board.cmake b/hw/bsp/msp430/boards/msp_exp430f5529lp/board.cmake new file mode 100644 index 000000000..59f591263 --- /dev/null +++ b/hw/bsp/msp430/boards/msp_exp430f5529lp/board.cmake @@ -0,0 +1,9 @@ +set(MCU_VARIANT msp430f5529) +set(LD_FILE_GNU ${SDK_DIR}/msp430f5529.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} INTERFACE + __MSP430F5529__ + ) + +endfunction() diff --git a/hw/bsp/msp430/family.cmake b/hw/bsp/msp430/family.cmake new file mode 100644 index 000000000..e0b4ed28a --- /dev/null +++ b/hw/bsp/msp430/family.cmake @@ -0,0 +1,84 @@ +include_guard() + +set(SDK_DIR ${TOP}/hw/mcu/ti/msp430/msp430-gcc-support-files/include) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR msp430 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/msp430_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS MSP430x5xx CACHE INTERNAL "") + + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (NOT TARGET ${BOARD_TARGET}) + add_library(${BOARD_TARGET} INTERFACE) + target_compile_definitions(${BOARD_TARGET} INTERFACE + CFG_TUD_ENDPOINT0_SIZE=8 + CFG_EXAMPLE_VIDEO_READONLY + CFG_EXAMPLE_MSC_READONLY + ) + target_include_directories(${BOARD_TARGET} INTERFACE + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${SDK_DIR} + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} INTERFACE + "LINKER:--script=${LD_FILE_GNU}" + -L${SDK_DIR} + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} INTERFACE + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () + 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_MSP430x5xx ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/ti/msp430x5xx/dcd_msp430x5xx.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_msp430flasher(${TARGET}) +endfunction() diff --git a/hw/bsp/msp430/family.mk b/hw/bsp/msp430/family.mk index ceafa6ec1..f1c6f9cf2 100644 --- a/hw/bsp/msp430/family.mk +++ b/hw/bsp/msp430/family.mk @@ -2,6 +2,8 @@ CROSS_COMPILE = msp430-elf- DEPS_SUBMODULES += hw/mcu/ti SKIP_NANOLIB = 1 +SDK_DIR = hw/mcu/ti/msp430/msp430-gcc-support-files/include + CFLAGS += \ -D__MSP430F5529__ \ -DCFG_TUSB_MCU=OPT_MCU_MSP430x5xx \ @@ -9,14 +11,13 @@ CFLAGS += \ -DCFG_TUD_ENDPOINT0_SIZE=8 # All source paths should be relative to the top level. -LD_FILE = hw/mcu/ti/msp430/msp430-gcc-support-files/include/msp430f5529.ld -LDINC += $(TOP)/hw/mcu/ti/msp430/msp430-gcc-support-files/include -LDFLAGS += $(addprefix -L,$(LDINC)) +LD_FILE = ${SDK_DIR}/msp430f5529.ld +LDFLAGS += -L${TOP}/${SDK_DIR} SRC_C += src/portable/ti/msp430x5xx/dcd_msp430x5xx.c INC += \ - $(TOP)/hw/mcu/ti/msp430/msp430-gcc-support-files/include \ + ${TOP}/${SDK_DIR} \ $(TOP)/$(BOARD_PATH) # export for libmsp430.so to same installation From bf649988ef8ffd39435dddc747f953faf78db471 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 15 Apr 2024 12:06:13 +0700 Subject: [PATCH 296/454] add blocking delay for msp430 with max 25mhz --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 4 +- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 59 ++++++++++--------- 2 files changed, 33 insertions(+), 30 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 7bf726f3f..bb96b4937 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -544,14 +544,14 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) { * - 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 40 cycles (count = 20). + * 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 2 cycle (1 cycle for sub, 1 cycle for compare/jump) + cycle_count--; // each count take 3 cycles (1 for sub, jump, and compare) } #endif diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index 870cd725d..8005f5f7b 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -154,14 +154,11 @@ void dcd_init (uint8_t rhport) USBVECINT = 0; - if(USBPWRCTL & USBBGVBV) // Bus power detected? - { + if(USBPWRCTL & USBBGVBV) {// Bus power detected? USBPWRCTL |= VBOFFIE; // Enable bus-power-removed interrupt. USBIE |= RSTRIE; // Enable reset and wait for it before continuing. USBCNF |= PUR_EN; // Enable pullup. - } - else - { + } else { USBPWRCTL |= VBONIE; // Enable bus-power-applied interrupt. USBCNF &= ~USB_EN; // Disable USB module until bus power is detected. } @@ -639,8 +636,7 @@ static void handle_setup_packet(void) _setup_packet[i] = setup_buf[i]; } - // Force NAKs until tinyusb can handle the SETUP packet and prepare - // for a new xfer. + // Force NAKs until tinyusb can handle the SETUP packet and prepare for a new xfer. USBIEPCNT_0 |= NAK; USBOEPCNT_0 |= NAK; @@ -660,16 +656,28 @@ static void handle_setup_packet(void) dcd_event_setup_received(0, (uint8_t*) &_setup_packet[0], true); } -static void handle_bus_power_event(void *param) -{ +#if CFG_TUSB_OS == OPT_OS_NONE +TU_ATTR_ALWAYS_INLINE static inline void tu_delay(uint32_t ms) { + // msp430 can run up to 25Mhz -> 40ns per cycle. 1 ms = 25000 cycles + // each loop need 4 cycle: 1 sub, 1 cmp, 1 jump, 1 nop + volatile uint32_t cycles = (25000 * ms) >> 2; + while (cycles > 0) { + cycles--; + asm("nop"); + } +} +#else +#define tu_delay(ms) osal_task_delay(ms) +#endif + +static void handle_bus_power_event(void *param) { (void) param; - osal_task_delay(5); // Bus power settling delay. + tu_delay(5); // Bus power settling delay. USBKEYPID = USBKEY; - if(USBPWRCTL & USBBGVBV) // Event caused by application of bus power. - { + if(USBPWRCTL & USBBGVBV) { // Event caused by application of bus power. USBPWRCTL |= VBOFFIE; // Enable bus-power-removed interrupt. USBPLLDIVB = USBPLLDIVB; // For some reason the PLL will *NOT* lock unless the divider // register is re-written. The assumption here is that this @@ -678,21 +686,17 @@ static void handle_bus_power_event(void *param) USBPLLCTL |= (UPLLEN | UPFDEN); // Enable the PLL. uint16_t attempts = 0; - - do // Poll the PLL, checking for a successful lock. - { + do { // Poll the PLL, checking for a successful lock. USBPLLIR = 0; - osal_task_delay(1); + tu_delay(1); attempts++; } while ((attempts < 10) && (USBPLLIR != 0)); - if(!USBPLLIR) // A successful lock is indicated by all PLL-related interrupt - { // flags being cleared. + // A successful lock is indicated by all PLL-related interrupt flags being cleared. + if(!USBPLLIR) { dcd_init(0); // Re-initialize the USB module. } - } - else // Event caused by removal of bus power. - { + } else { // Event caused by removal of bus power. USBPWRCTL |= VBONIE; // Enable bus-power-applied interrupt. USBPLLCTL &= ~(UPLLEN | UPFDEN); // Disable the PLL. USBCNF = 0; // Disable the USB module. @@ -741,20 +745,19 @@ void dcd_int_handler(uint8_t rhport) break; case USBVECINT_PWR_VBUSOn: - case USBVECINT_PWR_VBUSOff: + case USBVECINT_PWR_VBUSOff: { USBKEYPID = USBKEY; // Prevent (possibly) unstable power from generating spurious interrupts. USBPWRCTL &= ~(VBONIE | VBOFFIE); USBKEYPID = 0; - { - dcd_event_t event; + dcd_event_t event; - event.rhport = 0; - event.event_id = USBD_EVENT_FUNC_CALL; - event.func_call.func = handle_bus_power_event; + event.rhport = 0; + event.event_id = USBD_EVENT_FUNC_CALL; + event.func_call.func = handle_bus_power_event; - dcd_event_handler(&event, true); + dcd_event_handler(&event, true); } break; From b2acbd305d29cea15fb4bd8e5cbc464546fdd8b7 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 15 Apr 2024 12:52:10 +0700 Subject: [PATCH 297/454] use cmake to build msp430 --- .github/workflows/build_msp430.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build_msp430.yml b/.github/workflows/build_msp430.yml index f913df913..53921b308 100644 --- a/.github/workflows/build_msp430.yml +++ b/.github/workflows/build_msp430.yml @@ -63,8 +63,7 @@ jobs: - 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 }} + run: | + python3 tools/get_deps.py ${{ matrix.family }} + python tools/build_cmake.py ${{ matrix.family }} -DCMAKE_BUILD_TYPE=MinSizeRel From 9561e3826700c872ccde111d52cb381da939a25c Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 15 Apr 2024 22:35:52 +0700 Subject: [PATCH 298/454] install ninja build for msp430 --- .github/workflows/build_msp430.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_msp430.yml b/.github/workflows/build_msp430.yml index 53921b308..95d212708 100644 --- a/.github/workflows/build_msp430.yml +++ b/.github/workflows/build_msp430.yml @@ -61,7 +61,9 @@ jobs: tar -C ~/cache/toolchain -xaf toolchain.tar.bz2 - name: Set Toolchain Path - run: echo >> $GITHUB_PATH `echo ~/cache/toolchain/*/bin` + run: | + echo >> $GITHUB_PATH `echo ~/cache/toolchain/*/bin` + sudo apt install -y ninja-build - name: Build run: | From afb66a955c51f6ef36d0e544c44ee06a88eb2b2b Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 15 Apr 2024 22:49:08 +0700 Subject: [PATCH 299/454] update msp430 make build --- examples/build_system/make/cpu/msp430.mk | 8 ++++++++ hw/bsp/msp430/boards/msp_exp430f5529lp/board.mk | 4 ++++ hw/bsp/msp430/family.mk | 5 ++--- 3 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 examples/build_system/make/cpu/msp430.mk create mode 100644 hw/bsp/msp430/boards/msp_exp430f5529lp/board.mk diff --git a/examples/build_system/make/cpu/msp430.mk b/examples/build_system/make/cpu/msp430.mk new file mode 100644 index 000000000..06340d23b --- /dev/null +++ b/examples/build_system/make/cpu/msp430.mk @@ -0,0 +1,8 @@ +ifeq ($(TOOLCHAIN),gcc) + # nothing to add +else ifeq ($(TOOLCHAIN),iar) + # nothing to add +endif + +# For freeRTOS port source +FREERTOS_PORTABLE_SRC ?= $(FREERTOS_PORTABLE_PATH)/GCC_MSP430F449 diff --git a/hw/bsp/msp430/boards/msp_exp430f5529lp/board.mk b/hw/bsp/msp430/boards/msp_exp430f5529lp/board.mk new file mode 100644 index 000000000..b45c62e83 --- /dev/null +++ b/hw/bsp/msp430/boards/msp_exp430f5529lp/board.mk @@ -0,0 +1,4 @@ +CFLAGS += \ + -D__MSP430F5529__ \ + +LD_FILE = ${SDK_DIR}/msp430f5529.ld diff --git a/hw/bsp/msp430/family.mk b/hw/bsp/msp430/family.mk index f1c6f9cf2..06508ab2c 100644 --- a/hw/bsp/msp430/family.mk +++ b/hw/bsp/msp430/family.mk @@ -4,14 +4,13 @@ SKIP_NANOLIB = 1 SDK_DIR = hw/mcu/ti/msp430/msp430-gcc-support-files/include +include $(TOP)/$(BOARD_PATH)/board.mk + CFLAGS += \ - -D__MSP430F5529__ \ -DCFG_TUSB_MCU=OPT_MCU_MSP430x5xx \ -DCFG_EXAMPLE_MSC_READONLY \ -DCFG_TUD_ENDPOINT0_SIZE=8 -# All source paths should be relative to the top level. -LD_FILE = ${SDK_DIR}/msp430f5529.ld LDFLAGS += -L${TOP}/${SDK_DIR} SRC_C += src/portable/ti/msp430x5xx/dcd_msp430x5xx.c From 6328301bb652458ad752b05129e1944404adc7ca Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 15 Apr 2024 23:56:55 +0700 Subject: [PATCH 300/454] revert to use __builtin_ctz() for optimized time --- src/portable/renesas/rusb2/dcd_rusb2.c | 22 ++++++++++++++----- src/portable/renesas/rusb2/hcd_rusb2.c | 30 +++++++++++++------------- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/src/portable/renesas/rusb2/dcd_rusb2.c b/src/portable/renesas/rusb2/dcd_rusb2.c index f9523191a..50400d1f5 100644 --- a/src/portable/renesas/rusb2/dcd_rusb2.c +++ b/src/portable/renesas/rusb2/dcd_rusb2.c @@ -915,6 +915,18 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) //--------------------------------------------------------------------+ // ISR //--------------------------------------------------------------------+ + +#if defined(__CCRX__) +TU_ATTR_ALWAYS_INLINE static inline unsigned __builtin_ctz(unsigned int value) { + unsigned int count = 0; + while ((value & 1) == 0) { + value >>= 1; + count++; + } + return count; +} +#endif + void dcd_int_handler(uint8_t rhport) { rusb2_reg_t* rusb = RUSB2_REG(rhport); @@ -1002,13 +1014,13 @@ void dcd_int_handler(uint8_t rhport) // Buffer ready if ( is0 & RUSB2_INTSTS0_BRDY_Msk ) { const unsigned m = rusb->BRDYENB; - const unsigned s = rusb->BRDYSTS & m; + unsigned s = rusb->BRDYSTS & m; /* clear active bits (don't write 0 to already cleared bits according to the HW manual) */ rusb->BRDYSTS = ~s; - for (unsigned p = 0; p < PIPE_COUNT; ++p) { - if (tu_bit_test(s, p)) { - process_pipe_brdy(rhport, p); - } + while (s) { + const unsigned num = __builtin_ctz(s); + process_pipe_brdy(rhport, num); + s &= ~TU_BIT(num); } } } diff --git a/src/portable/renesas/rusb2/hcd_rusb2.c b/src/portable/renesas/rusb2/hcd_rusb2.c index 1356b696f..f140da690 100644 --- a/src/portable/renesas/rusb2/hcd_rusb2.c +++ b/src/portable/renesas/rusb2/hcd_rusb2.c @@ -758,6 +758,17 @@ bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { //--------------------------------------------------------------------+ // ISR //--------------------------------------------------------------------+ +#if defined(__CCRX__) +TU_ATTR_ALWAYS_INLINE static inline unsigned __builtin_ctz(unsigned int value) { + unsigned int count = 0; + while ((value & 1) == 0) { + value >>= 1; + count++; + } + return count; +} +#endif + void hcd_int_handler(uint8_t rhport, bool in_isr) { (void) in_isr; @@ -807,23 +818,12 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { } } -#if defined(__CCRX__) - static const int Mod37BitPosition[] = { - -1, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13, 4, - 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9, 5, - 20, 8, 19, 18}; -#endif - if (is0 & RUSB2_INTSTS0_NRDY_Msk) { const unsigned m = rusb->NRDYENB; unsigned s = rusb->NRDYSTS & m; rusb->NRDYSTS = ~s; while (s) { -#if defined(__CCRX__) - const unsigned num = Mod37BitPosition[(-s & s) % 37]; -#else const unsigned num = __builtin_ctz(s); -#endif process_pipe_nrdy(rhport, num); s &= ~TU_BIT(num); } @@ -833,10 +833,10 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { unsigned s = rusb->BRDYSTS & m; /* clear active bits (don't write 0 to already cleared bits according to the HW manual) */ rusb->BRDYSTS = ~s; - for (unsigned p = 0; p < PIPE_COUNT; ++p) { - if (tu_bit_test(s, p)) { - process_pipe_brdy(rhport, p); - } + while (s) { + const unsigned num = __builtin_ctz(s); + process_pipe_brdy(rhport, num); + s &= ~TU_BIT(num); } } } From 9588c3fac9e6625e73357f6edddd12f6d11cbd7d Mon Sep 17 00:00:00 2001 From: NConrad Date: Tue, 28 Jun 2022 23:26:54 -0400 Subject: [PATCH 301/454] USBD: When SET_FEATURE(ENDPOINT_HALT), the DTOG must be reset. --- 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 96982c30b..034a9ae09 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -636,7 +636,7 @@ static bool invoke_class_control(uint8_t rhport, usbd_class_driver_t const * dri } // This handles the actual request and its response. -// return false will cause its caller to stall control endpoint +// Returns false if unable to complete the request, causing caller to stall control endpoints. static bool process_control_request(uint8_t rhport, tusb_control_request_t const * p_request) { usbd_control_set_complete_callback(NULL); TU_ASSERT(p_request->bmRequestType_bit.type < TUSB_REQ_TYPE_INVALID); From 5dabef79eeb7d6ca271b2a09abddb700bc59ca03 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 16 Apr 2024 10:27:16 +0700 Subject: [PATCH 302/454] don't check local endpoint stalled status, just carry the request for host. --- src/device/usbd.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index 034a9ae09..109c3462d 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -1306,12 +1306,10 @@ void usbd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { uint8_t const dir = tu_edpt_dir(ep_addr); // only stalled if currently cleared - if (!_usbd_dev.ep_status[epnum][dir].stalled) { - TU_LOG_USBD(" Stall EP %02X\r\n", ep_addr); - dcd_edpt_stall(rhport, ep_addr); - _usbd_dev.ep_status[epnum][dir].stalled = 1; - _usbd_dev.ep_status[epnum][dir].busy = 1; - } + TU_LOG_USBD(" Stall EP %02X\r\n", ep_addr); + dcd_edpt_stall(rhport, ep_addr); + _usbd_dev.ep_status[epnum][dir].stalled = 1; + _usbd_dev.ep_status[epnum][dir].busy = 1; } void usbd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { @@ -1321,12 +1319,10 @@ void usbd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { uint8_t const dir = tu_edpt_dir(ep_addr); // only clear if currently stalled - if (_usbd_dev.ep_status[epnum][dir].stalled) { - TU_LOG_USBD(" Clear Stall EP %02X\r\n", ep_addr); - dcd_edpt_clear_stall(rhport, ep_addr); - _usbd_dev.ep_status[epnum][dir].stalled = 0; - _usbd_dev.ep_status[epnum][dir].busy = 0; - } + TU_LOG_USBD(" Clear Stall EP %02X\r\n", ep_addr); + dcd_edpt_clear_stall(rhport, ep_addr); + _usbd_dev.ep_status[epnum][dir].stalled = 0; + _usbd_dev.ep_status[epnum][dir].busy = 0; } bool usbd_edpt_stalled(uint8_t rhport, uint8_t ep_addr) { From 189080b684b298e0b3e7df6528f24a43c646ab8c Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 16 Apr 2024 10:40:24 +0700 Subject: [PATCH 303/454] add TU_ASSERT() to check for adding new usb event --- src/device/usbd.c | 4 ++-- src/host/usbh.c | 4 ++-- src/osal/osal_none.h | 1 - src/osal/osal_pico.h | 1 - 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index 96982c30b..76b7b3ee5 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -296,9 +296,9 @@ tu_static osal_queue_t _usbd_q; #endif TU_ATTR_ALWAYS_INLINE static inline bool queue_event(dcd_event_t const * event, bool in_isr) { - bool ret = osal_queue_send(_usbd_q, event, in_isr); + TU_ASSERT(osal_queue_send(_usbd_q, event, in_isr)); tud_event_hook_cb(event->rhport, event->event_id, in_isr); - return ret; + return true; } //--------------------------------------------------------------------+ diff --git a/src/host/usbh.c b/src/host/usbh.c index 6a5491998..f8fddf394 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -288,9 +288,9 @@ TU_ATTR_WEAK void osal_task_delay(uint32_t msec) { #endif TU_ATTR_ALWAYS_INLINE static inline bool queue_event(hcd_event_t const * event, bool in_isr) { - bool ret = osal_queue_send(_usbh_q, event, in_isr); + TU_ASSERT(osal_queue_send(_usbh_q, event, in_isr)); tuh_event_hook_cb(event->rhport, event->event_id, in_isr); - return ret; + return true; } //--------------------------------------------------------------------+ diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index c954fcfe8..c93f7a86c 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -180,7 +180,6 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void _osal_q_unlock(qhdl); } - TU_ASSERT(success); return success; } diff --git a/src/osal/osal_pico.h b/src/osal/osal_pico.h index 00c589ef9..315de0950 100644 --- a/src/osal/osal_pico.h +++ b/src/osal/osal_pico.h @@ -145,7 +145,6 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void bool success = tu_fifo_write(&qhdl->ff, data); critical_section_exit(&qhdl->critsec); - TU_ASSERT(success); return success; } From e1c3b5aeab46de79b08b0655e8ece2c37a0f1a92 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 16 Apr 2024 10:57:54 +0700 Subject: [PATCH 304/454] minor update to sof --- src/portable/synopsys/dwc2/dcd_dwc2.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 830a1ccd0..a824226c7 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -1136,16 +1136,14 @@ void dcd_int_handler(uint8_t rhport) { if(int_status & GINTSTS_SOF) { dwc2->gintsts = GINTSTS_SOF; + const uint32_t frame = (dwc2->dsts & DSTS_FNSOF) >> DSTS_FNSOF_Pos; - if (_sof_en) { - uint32_t frame = (dwc2->dsts & (DSTS_FNSOF)) >> 8; - dcd_event_sof(rhport, frame, true); - } else { - // Disable SOF interrupt if SOF was not explicitly enabled. SOF was used for remote wakeup detection + // Disable SOF interrupt if SOF was not explicitly enabled since SOF was used for remote wakeup detection + if (!_sof_en) { dwc2->gintmsk &= ~GINTMSK_SOFM; } - dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); + dcd_event_sof(rhport, frame, true); } // RxFIFO non-empty interrupt handling. From 1b0ec6b1bd3135209451fab7909130a7b12c23f8 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Fri, 22 Sep 2023 18:26:36 +0200 Subject: [PATCH 305/454] make it compile also with old Nordic SDK --- src/portable/nordic/nrf5x/dcd_nrf5x.c | 71 +++++++++++++++++++++------ 1 file changed, 55 insertions(+), 16 deletions(-) diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index 80a285ef0..e831a09de 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -40,7 +40,6 @@ #include "nrf.h" #include "nrf_clock.h" -#include "nrf_power.h" #include "nrfx_usbd_errata.h" #ifdef __GNUC__ @@ -57,6 +56,13 @@ #include "mcu/mcu.h" #endif +#if 1000*MDK_MAJOR_VERSION + MDK_MINOR_VERSION <= 8040 +// Nordic actually has generated a mess here: nrfx==1.9.0 has MDK 8.40.3 while nrfx==2.0.0 has MDK 8.29.0 +// Unfortunately there are API differences between nrfx<2.0.0 and nrfx>=2.0.0. Hoping that everyone uses +// nRF Connect SDK keeps the libraries up to date. +#define OLD_NORDIC_SDK +#endif + /*------------------------------------------------------------------*/ /* MACRO TYPEDEF CONSTANT ENUM *------------------------------------------------------------------*/ @@ -110,21 +116,6 @@ static struct /* Control / Bulk / Interrupt (CBI) Transfer *------------------------------------------------------------------*/ -// NVIC_GetEnableIRQ is only available in CMSIS v5 -#ifndef NVIC_GetEnableIRQ -static inline uint32_t NVIC_GetEnableIRQ(IRQn_Type IRQn) -{ - if ((int32_t)(IRQn) >= 0) - { - return((uint32_t)(((NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); - } - else - { - return(0U); - } -} -#endif - // check if we are in ISR TU_ATTR_ALWAYS_INLINE static inline bool is_in_isr(void) { @@ -253,13 +244,27 @@ void dcd_init (uint8_t rhport) void dcd_int_enable(uint8_t rhport) { (void) rhport; +#ifdef SOFTDEVICE_PRESENT + if (sd_nvic_EnableIRQ(USBD_IRQn) != NRF_SUCCESS) + { + NVIC_EnableIRQ(USBD_IRQn); + } +#else NVIC_EnableIRQ(USBD_IRQn); +#endif } void dcd_int_disable(uint8_t rhport) { (void) rhport; +#ifdef SOFTDEVICE_PRESENT + if (sd_nvic_DisableIRQ(USBD_IRQn) != NRF_SUCCESS) + { + NVIC_DisableIRQ(USBD_IRQn); + } +#else NVIC_DisableIRQ(USBD_IRQn); +#endif } void dcd_set_address (uint8_t rhport, uint8_t dev_addr) @@ -916,7 +921,11 @@ static bool hfclk_running(void) } #endif +#ifdef OLD_NORDIC_SDK + return nrf_clock_hf_is_running(NRF_CLOCK_HFCLK_HIGH_ACCURACY); +#else return nrf_clock_hf_is_running(NRF_CLOCK, NRF_CLOCK_HFCLK_HIGH_ACCURACY); +#endif } static void hfclk_enable(void) @@ -937,9 +946,14 @@ static void hfclk_enable(void) } #endif +#ifdef OLD_NORDIC_SDK + nrf_clock_event_clear(NRF_CLOCK_EVENT_HFCLKSTARTED); + nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTART); +#else nrf_clock_event_clear(NRF_CLOCK, NRF_CLOCK_EVENT_HFCLKSTARTED); nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTART); #endif +#endif } static void hfclk_disable(void) @@ -957,8 +971,12 @@ static void hfclk_disable(void) } #endif +#ifdef OLD_NORDIC_SDK + nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTOP); +#else nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTOP); #endif +#endif } // Power & Clock Peripheral on nRF5x to manage USB @@ -1100,13 +1118,27 @@ void tusb_hal_nrf_power_event (uint32_t event) NRF_USBD->INTENSET = USBD_INTEN_USBRESET_Msk; // Enable interrupt, priorities should be set by application +#ifdef SOFTDEVICE_PRESENT + if (sd_nvic_ClearPendingIRQ(USBD_IRQn) != NRF_SUCCESS) + { + NVIC_ClearPendingIRQ(USBD_IRQn); + } +#else NVIC_ClearPendingIRQ(USBD_IRQn); +#endif // Don't enable USBD interrupt yet, if dcd_init() did not finish yet // Interrupt will be enabled by tud_init(), when USB stack is ready // to handle interrupts. if (tud_inited()) { +#ifdef SOFTDEVICE_PRESENT + if (sd_nvic_EnableIRQ(USBD_IRQn) != NRF_SUCCESS) + { + NVIC_EnableIRQ(USBD_IRQn); + } +#else NVIC_EnableIRQ(USBD_IRQn); +#endif } // Wait for HFCLK @@ -1127,7 +1159,14 @@ void tusb_hal_nrf_power_event (uint32_t event) __ISB(); __DSB(); // for sync // Disable Interrupt +#ifdef SOFTDEVICE_PRESENT + if (sd_nvic_DisableIRQ(USBD_IRQn) != NRF_SUCCESS) + { + NVIC_DisableIRQ(USBD_IRQn); + } +#else NVIC_DisableIRQ(USBD_IRQn); +#endif // disable all interrupt NRF_USBD->INTENCLR = NRF_USBD->INTEN; From 2567fe3fd8b69e896b1d29de36d295ee007e5c91 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Fri, 22 Sep 2023 18:39:00 +0200 Subject: [PATCH 306/454] softdevice nvic calls only if old SDK --- src/portable/nordic/nrf5x/dcd_nrf5x.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index e831a09de..0e645ec46 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -244,7 +244,7 @@ void dcd_init (uint8_t rhport) void dcd_int_enable(uint8_t rhport) { (void) rhport; -#ifdef SOFTDEVICE_PRESENT +#if defined(SOFTDEVICE_PRESENT) && defined(OLD_NORDIC_SDK) if (sd_nvic_EnableIRQ(USBD_IRQn) != NRF_SUCCESS) { NVIC_EnableIRQ(USBD_IRQn); @@ -257,7 +257,7 @@ void dcd_int_enable(uint8_t rhport) void dcd_int_disable(uint8_t rhport) { (void) rhport; -#ifdef SOFTDEVICE_PRESENT +#if defined(SOFTDEVICE_PRESENT) && defined(OLD_NORDIC_SDK) if (sd_nvic_DisableIRQ(USBD_IRQn) != NRF_SUCCESS) { NVIC_DisableIRQ(USBD_IRQn); @@ -1118,7 +1118,7 @@ void tusb_hal_nrf_power_event (uint32_t event) NRF_USBD->INTENSET = USBD_INTEN_USBRESET_Msk; // Enable interrupt, priorities should be set by application -#ifdef SOFTDEVICE_PRESENT +#if defined(SOFTDEVICE_PRESENT) && defined(OLD_NORDIC_SDK) if (sd_nvic_ClearPendingIRQ(USBD_IRQn) != NRF_SUCCESS) { NVIC_ClearPendingIRQ(USBD_IRQn); @@ -1131,7 +1131,7 @@ void tusb_hal_nrf_power_event (uint32_t event) // to handle interrupts. if (tud_inited()) { -#ifdef SOFTDEVICE_PRESENT +#if defined(SOFTDEVICE_PRESENT) && defined(OLD_NORDIC_SDK) if (sd_nvic_EnableIRQ(USBD_IRQn) != NRF_SUCCESS) { NVIC_EnableIRQ(USBD_IRQn); @@ -1159,7 +1159,7 @@ void tusb_hal_nrf_power_event (uint32_t event) __ISB(); __DSB(); // for sync // Disable Interrupt -#ifdef SOFTDEVICE_PRESENT +#if defined(SOFTDEVICE_PRESENT) && defined(OLD_NORDIC_SDK) if (sd_nvic_DisableIRQ(USBD_IRQn) != NRF_SUCCESS) { NVIC_DisableIRQ(USBD_IRQn); From c535a4d42be742f235126fa679bf65a6751360cc Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Sat, 25 Nov 2023 14:49:49 +0100 Subject: [PATCH 307/454] catch all nrfx versions with an old API --- src/portable/nordic/nrf5x/dcd_nrf5x.c | 40 ++++++++++++++++++--------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index 0e645ec46..f5eea1310 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -56,11 +56,25 @@ #include "mcu/mcu.h" #endif -#if 1000*MDK_MAJOR_VERSION + MDK_MINOR_VERSION <= 8040 -// Nordic actually has generated a mess here: nrfx==1.9.0 has MDK 8.40.3 while nrfx==2.0.0 has MDK 8.29.0 -// Unfortunately there are API differences between nrfx<2.0.0 and nrfx>=2.0.0. Hoping that everyone uses -// nRF Connect SDK keeps the libraries up to date. -#define OLD_NORDIC_SDK +// Unfortunately there are API differences between nrfx<2.0.0 and nrfx>=2.0.0 +// Nordic actually has generated a mess here: nrfx==1.9.0 has MDK 8.40.3 while nrfx==2.0.0 has MDK 8.29.0. +// See the below statement to catch all nrfx versions with an old API. +#define _MDK_VERSION 10000*MDK_MAJOR_VERSION + 100*MDK_MINOR_VERSION + MDK_MICRO_VERSION +#if _MDK_VERSION <= 82701 + // nrfx <= 1.8.1 + #define NORDIC_SDK_OLD_API +#elif _MDK_VERSION == 83201 + // nrfx 1.8.2 / 1.8.4 + #define NORDIC_SDK_OLD_API +#elif _MDK_VERSION == 83203 + // nrfx 1.8.5 + #define NORDIC_SDK_OLD_API +#elif _MDK_VERSION == 83500 + // nrfx 1.8.6 + #define NORDIC_SDK_OLD_API +#elif _MDK_VERSION == 84003 + // nrfx 1.9.0 + #define NORDIC_SDK_OLD_API #endif /*------------------------------------------------------------------*/ @@ -244,7 +258,7 @@ void dcd_init (uint8_t rhport) void dcd_int_enable(uint8_t rhport) { (void) rhport; -#if defined(SOFTDEVICE_PRESENT) && defined(OLD_NORDIC_SDK) +#if defined(SOFTDEVICE_PRESENT) && defined(NORDIC_SDK_OLD_API) if (sd_nvic_EnableIRQ(USBD_IRQn) != NRF_SUCCESS) { NVIC_EnableIRQ(USBD_IRQn); @@ -257,7 +271,7 @@ void dcd_int_enable(uint8_t rhport) void dcd_int_disable(uint8_t rhport) { (void) rhport; -#if defined(SOFTDEVICE_PRESENT) && defined(OLD_NORDIC_SDK) +#if defined(SOFTDEVICE_PRESENT) && defined(NORDIC_SDK_OLD_API) if (sd_nvic_DisableIRQ(USBD_IRQn) != NRF_SUCCESS) { NVIC_DisableIRQ(USBD_IRQn); @@ -921,7 +935,7 @@ static bool hfclk_running(void) } #endif -#ifdef OLD_NORDIC_SDK +#ifdef NORDIC_SDK_OLD_API return nrf_clock_hf_is_running(NRF_CLOCK_HFCLK_HIGH_ACCURACY); #else return nrf_clock_hf_is_running(NRF_CLOCK, NRF_CLOCK_HFCLK_HIGH_ACCURACY); @@ -946,7 +960,7 @@ static void hfclk_enable(void) } #endif -#ifdef OLD_NORDIC_SDK +#ifdef NORDIC_SDK_OLD_API nrf_clock_event_clear(NRF_CLOCK_EVENT_HFCLKSTARTED); nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTART); #else @@ -971,7 +985,7 @@ static void hfclk_disable(void) } #endif -#ifdef OLD_NORDIC_SDK +#ifdef NORDIC_SDK_OLD_API nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTOP); #else nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTOP); @@ -1118,7 +1132,7 @@ void tusb_hal_nrf_power_event (uint32_t event) NRF_USBD->INTENSET = USBD_INTEN_USBRESET_Msk; // Enable interrupt, priorities should be set by application -#if defined(SOFTDEVICE_PRESENT) && defined(OLD_NORDIC_SDK) +#if defined(SOFTDEVICE_PRESENT) && defined(NORDIC_SDK_OLD_API) if (sd_nvic_ClearPendingIRQ(USBD_IRQn) != NRF_SUCCESS) { NVIC_ClearPendingIRQ(USBD_IRQn); @@ -1131,7 +1145,7 @@ void tusb_hal_nrf_power_event (uint32_t event) // to handle interrupts. if (tud_inited()) { -#if defined(SOFTDEVICE_PRESENT) && defined(OLD_NORDIC_SDK) +#if defined(SOFTDEVICE_PRESENT) && defined(NORDIC_SDK_OLD_API) if (sd_nvic_EnableIRQ(USBD_IRQn) != NRF_SUCCESS) { NVIC_EnableIRQ(USBD_IRQn); @@ -1159,7 +1173,7 @@ void tusb_hal_nrf_power_event (uint32_t event) __ISB(); __DSB(); // for sync // Disable Interrupt -#if defined(SOFTDEVICE_PRESENT) && defined(OLD_NORDIC_SDK) +#if defined(SOFTDEVICE_PRESENT) && defined(NORDIC_SDK_OLD_API) if (sd_nvic_DisableIRQ(USBD_IRQn) != NRF_SUCCESS) { NVIC_DisableIRQ(USBD_IRQn); From 37a05e02647a188f562e763ab24cdbd9f48cf434 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 16 Apr 2024 11:23:38 +0700 Subject: [PATCH 308/454] revert nvic changes --- src/portable/nordic/nrf5x/dcd_nrf5x.c | 36 +-------------------------- 1 file changed, 1 insertion(+), 35 deletions(-) diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index f5eea1310..5f2de6446 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -258,27 +258,13 @@ void dcd_init (uint8_t rhport) void dcd_int_enable(uint8_t rhport) { (void) rhport; -#if defined(SOFTDEVICE_PRESENT) && defined(NORDIC_SDK_OLD_API) - if (sd_nvic_EnableIRQ(USBD_IRQn) != NRF_SUCCESS) - { - NVIC_EnableIRQ(USBD_IRQn); - } -#else NVIC_EnableIRQ(USBD_IRQn); -#endif } void dcd_int_disable(uint8_t rhport) { (void) rhport; -#if defined(SOFTDEVICE_PRESENT) && defined(NORDIC_SDK_OLD_API) - if (sd_nvic_DisableIRQ(USBD_IRQn) != NRF_SUCCESS) - { - NVIC_DisableIRQ(USBD_IRQn); - } -#else NVIC_DisableIRQ(USBD_IRQn); -#endif } void dcd_set_address (uint8_t rhport, uint8_t dev_addr) @@ -1132,27 +1118,14 @@ void tusb_hal_nrf_power_event (uint32_t event) NRF_USBD->INTENSET = USBD_INTEN_USBRESET_Msk; // Enable interrupt, priorities should be set by application -#if defined(SOFTDEVICE_PRESENT) && defined(NORDIC_SDK_OLD_API) - if (sd_nvic_ClearPendingIRQ(USBD_IRQn) != NRF_SUCCESS) - { - NVIC_ClearPendingIRQ(USBD_IRQn); - } -#else NVIC_ClearPendingIRQ(USBD_IRQn); -#endif + // Don't enable USBD interrupt yet, if dcd_init() did not finish yet // Interrupt will be enabled by tud_init(), when USB stack is ready // to handle interrupts. if (tud_inited()) { -#if defined(SOFTDEVICE_PRESENT) && defined(NORDIC_SDK_OLD_API) - if (sd_nvic_EnableIRQ(USBD_IRQn) != NRF_SUCCESS) - { - NVIC_EnableIRQ(USBD_IRQn); - } -#else NVIC_EnableIRQ(USBD_IRQn); -#endif } // Wait for HFCLK @@ -1173,14 +1146,7 @@ void tusb_hal_nrf_power_event (uint32_t event) __ISB(); __DSB(); // for sync // Disable Interrupt -#if defined(SOFTDEVICE_PRESENT) && defined(NORDIC_SDK_OLD_API) - if (sd_nvic_DisableIRQ(USBD_IRQn) != NRF_SUCCESS) - { - NVIC_DisableIRQ(USBD_IRQn); - } -#else NVIC_DisableIRQ(USBD_IRQn); -#endif // disable all interrupt NRF_USBD->INTENCLR = NRF_USBD->INTEN; From d82ee79bd0a834a83694c91ce9cff67575283846 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 16 Apr 2024 11:55:03 +0700 Subject: [PATCH 309/454] - in case of mdk conflict to use nrfx v2 - allow to force nrfx version with CFG_TUD_NRF_NRFX_VERSION=1 --- src/portable/nordic/nrf5x/dcd_nrf5x.c | 43 +++++++++++++-------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index 5f2de6446..df5f275db 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -56,25 +56,24 @@ #include "mcu/mcu.h" #endif -// Unfortunately there are API differences between nrfx<2.0.0 and nrfx>=2.0.0 -// Nordic actually has generated a mess here: nrfx==1.9.0 has MDK 8.40.3 while nrfx==2.0.0 has MDK 8.29.0. -// See the below statement to catch all nrfx versions with an old API. -#define _MDK_VERSION 10000*MDK_MAJOR_VERSION + 100*MDK_MINOR_VERSION + MDK_MICRO_VERSION -#if _MDK_VERSION <= 82701 - // nrfx <= 1.8.1 - #define NORDIC_SDK_OLD_API -#elif _MDK_VERSION == 83201 - // nrfx 1.8.2 / 1.8.4 - #define NORDIC_SDK_OLD_API -#elif _MDK_VERSION == 83203 - // nrfx 1.8.5 - #define NORDIC_SDK_OLD_API -#elif _MDK_VERSION == 83500 - // nrfx 1.8.6 - #define NORDIC_SDK_OLD_API -#elif _MDK_VERSION == 84003 - // nrfx 1.9.0 - #define NORDIC_SDK_OLD_API +/* Try to detect nrfx version if not configured with CFG_TUD_NRF_NRFX_VERSION + * nrfx v1 and v2 are concurrently developed. There is no NRFX_VERSION only MDK VERSION which is as follows: + * - v2.6.0: 8.44.1, v2.5.0: 8.40.2, v2.4.0: 8.37.0, v2.3.0: 8.35.0, v2.2.0: 8.32.1, v2.1.0: 8.30.2, v2.0.0: 8.29.0 + * - v1.9.0: 8.40.3, v1.8.6: 8.35.0 (conflict with v2.3.0), v1.8.5: 8.32.3, v1.8.4: 8.32.1 (conflict with v2.2.0), + * v1.8.2: 8.32.1 (conflict with v2.2.0), v1.8.1: 8.27.1 + * Therefore the check for v1 would be: + * - MDK < 8.29.0 (v2.0), MDK == 8.32.3, 8.40.3 + * - in case of conflict User of those version must upgrade to other 1.x version or set CFG_TUD_NRF_NRFX_VERSION +*/ +#ifndef CFG_TUD_NRF_NRFX_VERSION + #define _MDK_VERSION (10000*MDK_MAJOR_VERSION + 100*MDK_MINOR_VERSION + MDK_MICRO_VERSION) + + #if _MDK_VERSION < 82900 || _MDK_VERSION == 83203 || _MDK_VERSION == 84003 + // nrfx <= 1.8.1, or 1.8.5 or 1.9.0 + #define CFG_TUD_NRF_NRFX_VERSION 1 + #else + #define CFG_TUD_NRF_NRFX_VERSION 2 + #endif #endif /*------------------------------------------------------------------*/ @@ -921,7 +920,7 @@ static bool hfclk_running(void) } #endif -#ifdef NORDIC_SDK_OLD_API +#if CFG_TUD_NRF_NRFX_VERSION == 1 return nrf_clock_hf_is_running(NRF_CLOCK_HFCLK_HIGH_ACCURACY); #else return nrf_clock_hf_is_running(NRF_CLOCK, NRF_CLOCK_HFCLK_HIGH_ACCURACY); @@ -946,7 +945,7 @@ static void hfclk_enable(void) } #endif -#ifdef NORDIC_SDK_OLD_API +#if CFG_TUD_NRF_NRFX_VERSION == 1 nrf_clock_event_clear(NRF_CLOCK_EVENT_HFCLKSTARTED); nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTART); #else @@ -971,7 +970,7 @@ static void hfclk_disable(void) } #endif -#ifdef NORDIC_SDK_OLD_API +#if CFG_TUD_NRF_NRFX_VERSION == 1 nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTOP); #else nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTOP); From 86710c9bb24111c9f1c9a2ec9623c89b987e93a8 Mon Sep 17 00:00:00 2001 From: yuxiaojun Date: Tue, 28 Nov 2023 17:14:05 +0800 Subject: [PATCH 310/454] fix: memory leak: buf Signed-off-by: yuxiaojun --- hw/mcu/sony/cxd56/mkspk/mkspk.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/hw/mcu/sony/cxd56/mkspk/mkspk.c b/hw/mcu/sony/cxd56/mkspk/mkspk.c index 3feb235f6..78d98a08e 100644 --- a/hw/mcu/sony/cxd56/mkspk/mkspk.c +++ b/hw/mcu/sony/cxd56/mkspk/mkspk.c @@ -183,6 +183,7 @@ static struct elf_file *load_elf(const char *filename) buf = (char *)malloc(fsize); if (!buf) { + free(ef); fclose(fp); return NULL; } @@ -191,6 +192,8 @@ static struct elf_file *load_elf(const char *filename) fclose(fp); if (ret != 1) { + free(ef); + free(buf); return NULL; } @@ -351,7 +354,11 @@ int main(int argc, char **argv) } spkimage = create_image(elf, args->core, args->savename, &size); + if(elf->data) { + free(elf->data); + } free(elf); + c = cipher_init(vmk, NULL); cipher_calc_cmac(c, spkimage, size, (uint8_t *) spkimage + size); From e03774be8828ac9b3cb9bfd5e80c769d338a8e0f Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 16 Apr 2024 12:04:43 +0700 Subject: [PATCH 311/454] skip symlink in pre-commit --- .pre-commit-config.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4071ec326..bba217cc9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,9 @@ repos: exclude: | (?x)^( .idea/| - hw/bsp/mcx/sdk/ + hw/bsp/mcx/sdk/| + docs/contributing/code_of_conduct.rst| + docs/info/contributors.rst ) - id: forbid-submodules From 10a86172ec5d1dd31122346776bff1f4ea1574e4 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 16 Apr 2024 12:06:26 +0700 Subject: [PATCH 312/454] fix pre-commit --- hw/mcu/sony/cxd56/mkspk/mkspk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/mcu/sony/cxd56/mkspk/mkspk.c b/hw/mcu/sony/cxd56/mkspk/mkspk.c index 78d98a08e..24e0cf77b 100644 --- a/hw/mcu/sony/cxd56/mkspk/mkspk.c +++ b/hw/mcu/sony/cxd56/mkspk/mkspk.c @@ -358,7 +358,7 @@ int main(int argc, char **argv) free(elf->data); } free(elf); - + c = cipher_init(vmk, NULL); cipher_calc_cmac(c, spkimage, size, (uint8_t *) spkimage + size); From bf29417e5fc1cd157e77510d23b05cf51cae2b34 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 16 Apr 2024 12:59:28 +0700 Subject: [PATCH 313/454] code format --- src/portable/nordic/nrf5x/dcd_nrf5x.c | 545 ++++++++++---------------- 1 file changed, 216 insertions(+), 329 deletions(-) diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index df5f275db..38d37bfc6 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -79,25 +79,22 @@ /*------------------------------------------------------------------*/ /* MACRO TYPEDEF CONSTANT ENUM *------------------------------------------------------------------*/ -enum -{ +enum { // Max allowed by USB specs - MAX_PACKET_SIZE = 64, + MAX_PACKET_SIZE = 64, // Mask of all END event (IN & OUT) for all endpoints. ENDEPIN0-7, ENDEPOUT0-7, ENDISOIN, ENDISOOUT EDPT_END_ALL_MASK = (0xff << USBD_INTEN_ENDEPIN0_Pos) | (0xff << USBD_INTEN_ENDEPOUT0_Pos) | USBD_INTENCLR_ENDISOIN_Msk | USBD_INTEN_ENDISOOUT_Msk }; -enum -{ - EP_ISO_NUM = 8, // Endpoint number is fixed (8) for ISOOUT and ISOIN +enum { + EP_ISO_NUM = 8, // Endpoint number is fixed (8) for ISOOUT and ISOIN EP_CBI_COUNT = 8 // Control Bulk Interrupt endpoints count }; // Transfer Descriptor -typedef struct -{ +typedef struct { uint8_t* buffer; uint16_t total_len; volatile uint16_t actual_len; @@ -115,98 +112,83 @@ typedef struct } xfer_td_t; // Data for managing dcd -static struct -{ +static struct { // All 8 endpoints including control IN & OUT (offset 1) // +1 for ISO endpoints xfer_td_t xfer[EP_CBI_COUNT + 1][2]; // nRF can only carry one DMA at a time, this is used to guard the access to EasyDMA atomic_bool dma_running; -}_dcd; +} _dcd; /*------------------------------------------------------------------*/ /* Control / Bulk / Interrupt (CBI) Transfer *------------------------------------------------------------------*/ // check if we are in ISR -TU_ATTR_ALWAYS_INLINE static inline bool is_in_isr(void) -{ +TU_ATTR_ALWAYS_INLINE static inline bool is_in_isr(void) { return (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) ? true : false; } // helper to start DMA -static void start_dma(volatile uint32_t* reg_startep) -{ +static void start_dma(volatile uint32_t* reg_startep) { (*reg_startep) = 1; - __ISB(); __DSB(); + __ISB(); + __DSB(); // TASKS_EP0STATUS, TASKS_EP0RCVOUT seem to need EasyDMA to be available // However these don't trigger any DMA transfer and got ENDED event subsequently // Therefore dma_pending is corrected right away - if ( (reg_startep == &NRF_USBD->TASKS_EP0STATUS) || (reg_startep == &NRF_USBD->TASKS_EP0RCVOUT) ) - { + if ((reg_startep == &NRF_USBD->TASKS_EP0STATUS) || (reg_startep == &NRF_USBD->TASKS_EP0RCVOUT)) { atomic_flag_clear(&_dcd.dma_running); } } -static void edpt_dma_start(volatile uint32_t* reg_startep) -{ - if ( atomic_flag_test_and_set(&_dcd.dma_running) ) - { +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) edpt_dma_start, (void*) (uintptr_t) reg_startep, true); - }else - { + } else { start_dma(reg_startep); } } // DMA is complete -static void edpt_dma_end(void) -{ - TU_ASSERT(_dcd.dma_running, ); +static void edpt_dma_end(void) { + TU_ASSERT(_dcd.dma_running,); atomic_flag_clear(&_dcd.dma_running); } // helper getting td -static inline xfer_td_t* get_td(uint8_t epnum, uint8_t dir) -{ +static inline xfer_td_t* get_td(uint8_t epnum, uint8_t dir) { return &_dcd.xfer[epnum][dir]; } static void xact_out_dma(uint8_t epnum); + // Function wraps xact_out_dma which wants uint8_t while usbd_defer_func wants void (*)(void *) -static void xact_out_dma_wrapper(void *epnum) -{ - xact_out_dma((uint8_t)((uintptr_t)epnum)); +static void xact_out_dma_wrapper(void* epnum) { + xact_out_dma((uint8_t) ((uintptr_t) epnum)); } // Start DMA to move data from Endpoint -> RAM -static void xact_out_dma(uint8_t epnum) -{ +static void xact_out_dma(uint8_t epnum) { xfer_td_t* xfer = get_td(epnum, TUSB_DIR_OUT); uint32_t xact_len; // DMA can't be active during read of SIZE.EPOUT or SIZE.ISOOUT, so try to lock, // If already running defer call regardless if it was called from ISR or task, - if ( atomic_flag_test_and_set(&_dcd.dma_running) ) - { - usbd_defer_func((osal_task_func_t)xact_out_dma_wrapper, (void *)(uint32_t)epnum, is_in_isr()); + if (atomic_flag_test_and_set(&_dcd.dma_running)) { + usbd_defer_func((osal_task_func_t) xact_out_dma_wrapper, (void*) (uint32_t) epnum, is_in_isr()); return; } - if (epnum == EP_ISO_NUM) - { + if (epnum == EP_ISO_NUM) { xact_len = NRF_USBD->SIZE.ISOOUT; // If ZERO bit is set, ignore ISOOUT length - if (xact_len & USBD_SIZE_ISOOUT_ZERO_Msk) - { + if (xact_len & USBD_SIZE_ISOOUT_ZERO_Msk) { xact_len = 0; atomic_flag_clear(&_dcd.dma_running); - } - else - { - if (xfer->started) - { + } else { + if (xfer->started) { // Trigger DMA move data from Endpoint -> SRAM NRF_USBD->ISOOUT.PTR = (uint32_t) xfer->buffer; NRF_USBD->ISOOUT.MAXCNT = xact_len; @@ -216,9 +198,7 @@ static void xact_out_dma(uint8_t epnum) atomic_flag_clear(&_dcd.dma_running); } } - } - else - { + } else { // limit xact len to remaining length xact_len = tu_min16((uint16_t) NRF_USBD->SIZE.EPOUT[epnum], xfer->total_len - xfer->actual_len); @@ -232,14 +212,13 @@ static void xact_out_dma(uint8_t epnum) // Prepare for a CBI transaction IN, call at the start // it start DMA to transfer data from RAM -> Endpoint -static void xact_in_dma(uint8_t epnum) -{ +static void xact_in_dma(uint8_t epnum) { xfer_td_t* xfer = get_td(epnum, TUSB_DIR_IN); // Each transaction is up to Max Packet Size uint16_t const xact_len = tu_min16(xfer->total_len - xfer->actual_len, xfer->mps); - NRF_USBD->EPIN[epnum].PTR = (uint32_t) xfer->buffer; + NRF_USBD->EPIN[epnum].PTR = (uint32_t) xfer->buffer; NRF_USBD->EPIN[epnum].MAXCNT = xact_len; edpt_dma_start(&NRF_USBD->TASKS_STARTEPIN[epnum]); @@ -248,26 +227,22 @@ static void xact_in_dma(uint8_t epnum) //--------------------------------------------------------------------+ // Controller API //--------------------------------------------------------------------+ -void dcd_init (uint8_t rhport) -{ +void dcd_init(uint8_t rhport) { TU_LOG2("dcd init\r\n"); (void) rhport; } -void dcd_int_enable(uint8_t rhport) -{ +void dcd_int_enable(uint8_t rhport) { (void) rhport; NVIC_EnableIRQ(USBD_IRQn); } -void dcd_int_disable(uint8_t rhport) -{ +void dcd_int_disable(uint8_t rhport) { (void) rhport; NVIC_DisableIRQ(USBD_IRQn); } -void dcd_set_address (uint8_t rhport, uint8_t dev_addr) -{ +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { (void) rhport; (void) dev_addr; // Set Address is automatically update by hw controller, nothing to do @@ -282,8 +257,7 @@ void dcd_set_address (uint8_t rhport, uint8_t dev_addr) NRF_USBD->INTENSET = USBD_INTEN_USBEVENT_Msk; } -void dcd_remote_wakeup(uint8_t rhport) -{ +void dcd_remote_wakeup(uint8_t rhport) { (void) rhport; // Bring controller out of low power mode @@ -292,8 +266,7 @@ void dcd_remote_wakeup(uint8_t rhport) } // disconnect by disabling internal pull-up resistor on D+/D- -void dcd_disconnect(uint8_t rhport) -{ +void dcd_disconnect(uint8_t rhport) { (void) rhport; NRF_USBD->USBPULLUP = 0; @@ -303,14 +276,12 @@ void dcd_disconnect(uint8_t rhport) } // connect by enabling internal pull-up resistor on D+/D- -void dcd_connect(uint8_t rhport) -{ +void dcd_connect(uint8_t rhport) { (void) rhport; NRF_USBD->USBPULLUP = 1; } -void dcd_sof_enable(uint8_t rhport, bool en) -{ +void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; (void) en; @@ -320,39 +291,32 @@ void dcd_sof_enable(uint8_t rhport, bool en) //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ -bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) -{ +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const* desc_edpt) { (void) rhport; uint8_t const ep_addr = desc_edpt->bEndpointAddress; - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); _dcd.xfer[epnum][dir].mps = tu_edpt_packet_size(desc_edpt); - if (desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS) - { - if (dir == TUSB_DIR_OUT) - { + if (desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS) { + if (dir == TUSB_DIR_OUT) { NRF_USBD->INTENSET = TU_BIT(USBD_INTEN_ENDEPOUT0_Pos + epnum); NRF_USBD->EPOUTEN |= TU_BIT(epnum); // Write any value to SIZE register will allow nRF to ACK/accept data NRF_USBD->SIZE.EPOUT[epnum] = 0; - }else - { + } else { NRF_USBD->INTENSET = TU_BIT(USBD_INTEN_ENDEPIN0_Pos + epnum); - NRF_USBD->EPINEN |= TU_BIT(epnum); + NRF_USBD->EPINEN |= TU_BIT(epnum); } // clear stall and reset DataToggle NRF_USBD->EPSTALL = (USBD_EPSTALL_STALL_UnStall << USBD_EPSTALL_STALL_Pos) | ep_addr; NRF_USBD->DTOGGLE = (USBD_DTOGGLE_VALUE_Data0 << USBD_DTOGGLE_VALUE_Pos) | ep_addr; - } - else - { + } else { TU_ASSERT(epnum == EP_ISO_NUM); - if (dir == TUSB_DIR_OUT) - { + if (dir == TUSB_DIR_OUT) { // SPLIT ISO buffer when ISO IN endpoint is already opened. if (_dcd.xfer[EP_ISO_NUM][TUSB_DIR_IN].mps) NRF_USBD->ISOSPLIT = USBD_ISOSPLIT_SPLIT_HalfIN; @@ -365,9 +329,7 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) // Enable SOF and ISOOUT interrupts, and ISOOUT endpoint. NRF_USBD->INTENSET = USBD_INTENSET_ENDISOOUT_Msk | USBD_INTENSET_SOF_Msk; NRF_USBD->EPOUTEN |= USBD_EPOUTEN_ISOOUT_Msk; - } - else - { + } else { NRF_USBD->EVENTS_ENDISOIN = 0; // SPLIT ISO buffer when ISO OUT endpoint is already opened. @@ -378,39 +340,38 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) // Enable SOF and ISOIN interrupts, and ISOIN endpoint. NRF_USBD->INTENSET = USBD_INTENSET_ENDISOIN_Msk | USBD_INTENSET_SOF_Msk; - NRF_USBD->EPINEN |= USBD_EPINEN_ISOIN_Msk; + NRF_USBD->EPINEN |= USBD_EPINEN_ISOIN_Msk; } } - __ISB(); __DSB(); + __ISB(); + __DSB(); return true; } -void dcd_edpt_close_all (uint8_t rhport) -{ +void dcd_edpt_close_all(uint8_t rhport) { // disable interrupt to prevent race condition dcd_int_disable(rhport); // disable all non-control (bulk + interrupt) endpoints - for ( uint8_t ep = 1; ep < EP_CBI_COUNT; ep++ ) - { + for (uint8_t ep = 1; ep < EP_CBI_COUNT; ep++) { NRF_USBD->INTENCLR = TU_BIT(USBD_INTEN_ENDEPOUT0_Pos + ep) | TU_BIT(USBD_INTEN_ENDEPIN0_Pos + ep); NRF_USBD->TASKS_STARTEPIN[ep] = 0; NRF_USBD->TASKS_STARTEPOUT[ep] = 0; - tu_memclr(_dcd.xfer[ep], 2*sizeof(xfer_td_t)); + tu_memclr(_dcd.xfer[ep], 2 * sizeof(xfer_td_t)); } // disable both ISO NRF_USBD->INTENCLR = USBD_INTENCLR_SOF_Msk | USBD_INTENCLR_ENDISOOUT_Msk | USBD_INTENCLR_ENDISOIN_Msk; NRF_USBD->ISOSPLIT = USBD_ISOSPLIT_SPLIT_OneDir; - NRF_USBD->TASKS_STARTISOIN = 0; + NRF_USBD->TASKS_STARTISOIN = 0; NRF_USBD->TASKS_STARTISOOUT = 0; - tu_memclr(_dcd.xfer[EP_ISO_NUM], 2*sizeof(xfer_td_t)); + tu_memclr(_dcd.xfer[EP_ISO_NUM], 2 * sizeof(xfer_td_t)); // de-activate all non-control NRF_USBD->EPOUTEN = 1UL; @@ -419,107 +380,89 @@ void dcd_edpt_close_all (uint8_t rhport) dcd_int_enable(rhport); } -void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) -{ +void dcd_edpt_close(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 dir = tu_edpt_dir(ep_addr); - if (epnum != EP_ISO_NUM) - { + if (epnum != EP_ISO_NUM) { // CBI - if (dir == TUSB_DIR_OUT) - { + if (dir == TUSB_DIR_OUT) { NRF_USBD->INTENCLR = TU_BIT(USBD_INTEN_ENDEPOUT0_Pos + epnum); NRF_USBD->EPOUTEN &= ~TU_BIT(epnum); - } - else - { + } else { NRF_USBD->INTENCLR = TU_BIT(USBD_INTEN_ENDEPIN0_Pos + epnum); NRF_USBD->EPINEN &= ~TU_BIT(epnum); } - } - else - { + } else { _dcd.xfer[EP_ISO_NUM][dir].mps = 0; // ISO - if (dir == TUSB_DIR_OUT) - { + if (dir == TUSB_DIR_OUT) { NRF_USBD->INTENCLR = USBD_INTENCLR_ENDISOOUT_Msk; NRF_USBD->EPOUTEN &= ~USBD_EPOUTEN_ISOOUT_Msk; NRF_USBD->EVENTS_ENDISOOUT = 0; - } - else - { + } else { NRF_USBD->INTENCLR = USBD_INTENCLR_ENDISOIN_Msk; NRF_USBD->EPINEN &= ~USBD_EPINEN_ISOIN_Msk; } // One of the ISO endpoints closed, no need to split buffers any more. NRF_USBD->ISOSPLIT = USBD_ISOSPLIT_SPLIT_OneDir; // When both ISO endpoint are close there is no need for SOF any more. - if (_dcd.xfer[EP_ISO_NUM][TUSB_DIR_IN].mps + _dcd.xfer[EP_ISO_NUM][TUSB_DIR_OUT].mps == 0) NRF_USBD->INTENCLR = USBD_INTENCLR_SOF_Msk; + if (_dcd.xfer[EP_ISO_NUM][TUSB_DIR_IN].mps + _dcd.xfer[EP_ISO_NUM][TUSB_DIR_OUT].mps == 0) + NRF_USBD->INTENCLR = USBD_INTENCLR_SOF_Msk; } _dcd.xfer[epnum][dir].started = false; - __ISB(); __DSB(); + __ISB(); + __DSB(); } -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) { (void) rhport; uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); xfer_td_t* xfer = get_td(epnum, dir); TU_ASSERT(!xfer->started); - xfer->buffer = buffer; - xfer->total_len = total_bytes; + xfer->buffer = buffer; + xfer->total_len = total_bytes; xfer->actual_len = 0; // Control endpoint with zero-length packet and opposite direction to 1st request byte --> status stage bool const control_status = (epnum == 0 && total_bytes == 0 && dir != tu_edpt_dir(NRF_USBD->BMREQUESTTYPE)); - if ( control_status ) - { + 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()); - } - else if ( dir == TUSB_DIR_OUT ) - { + } else if (dir == TUSB_DIR_OUT) { xfer->started = true; - if ( epnum == 0 ) - { + if (epnum == 0) { // Accept next Control Out packet. TASKS_EP0RCVOUT also require EasyDMA edpt_dma_start(&NRF_USBD->TASKS_EP0RCVOUT); - }else - { + } else { // started just set, it could start DMA transfer if interrupt was trigger after this line // code only needs to start transfer (from Endpoint to RAM) when data_received was set // before started was set. If started is NOT set but data_received is, it means that // current transfer was already finished and next data is already present in endpoint and // can be consumed by future transfer - __ISB(); __DSB(); - if ( xfer->data_received && xfer->started ) - { + __ISB(); + __DSB(); + if (xfer->data_received && xfer->started) { // Data is already received previously // start DMA to copy to SRAM xfer->data_received = false; xact_out_dma(epnum); - } - else - { + } else { // nRF auto accept next Bulk/Interrupt OUT packet // nothing to do } } - } - else - { + } else { // Start DMA to copy data from RAM -> Endpoint xact_in_dma(epnum); } @@ -527,42 +470,37 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t return true; } -void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) -{ +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 dir = tu_edpt_dir(ep_addr); xfer_td_t* xfer = get_td(epnum, dir); - if ( epnum == 0 ) - { + if (epnum == 0) { NRF_USBD->TASKS_EP0STALL = 1; - }else if (epnum != EP_ISO_NUM) - { + } else if (epnum != EP_ISO_NUM) { NRF_USBD->EPSTALL = (USBD_EPSTALL_STALL_Stall << USBD_EPSTALL_STALL_Pos) | ep_addr; // Note: nRF can auto ACK packet OUT before get stalled. // There maybe data in endpoint fifo already, we need to pull it out - if ( (dir == TUSB_DIR_OUT) && xfer->data_received ) - { + if ((dir == TUSB_DIR_OUT) && xfer->data_received) { xfer->data_received = false; xact_out_dma(epnum); } } - __ISB(); __DSB(); + __ISB(); + __DSB(); } -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; uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); - if ( epnum != 0 && epnum != EP_ISO_NUM ) - { + if (epnum != 0 && epnum != EP_ISO_NUM) { // reset data toggle to DATA0 // First write this register with VALUE=Nop to select the endpoint, then either read it to get the status from // VALUE, or write it again with VALUE=Data0 or Data1 @@ -575,26 +513,25 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) // Write any value to SIZE register will allow nRF to ACK/accept data if (dir == TUSB_DIR_OUT) NRF_USBD->SIZE.EPOUT[epnum] = 0; - __ISB(); __DSB(); + __ISB(); + __DSB(); } } /*------------------------------------------------------------------*/ /* Interrupt Handler *------------------------------------------------------------------*/ -void bus_reset(void) -{ +void bus_reset(void) { // 6.35.6 USB controller automatically disabled all endpoints (except control) NRF_USBD->EPOUTEN = 1UL; NRF_USBD->EPINEN = 1UL; - for(int i=0; i<8; i++) - { + for (int i = 0; i < 8; i++) { NRF_USBD->TASKS_STARTEPIN[i] = 0; NRF_USBD->TASKS_STARTEPOUT[i] = 0; } - NRF_USBD->TASKS_STARTISOIN = 0; + NRF_USBD->TASKS_STARTISOIN = 0; NRF_USBD->TASKS_STARTISOOUT = 0; // Clear USB Event Interrupt @@ -604,43 +541,40 @@ void bus_reset(void) // Reset interrupt NRF_USBD->INTENCLR = NRF_USBD->INTEN; NRF_USBD->INTENSET = USBD_INTEN_USBRESET_Msk | USBD_INTEN_USBEVENT_Msk | USBD_INTEN_EPDATA_Msk | - USBD_INTEN_EP0SETUP_Msk | USBD_INTEN_EP0DATADONE_Msk | USBD_INTEN_ENDEPIN0_Msk | USBD_INTEN_ENDEPOUT0_Msk; + USBD_INTEN_EP0SETUP_Msk | USBD_INTEN_EP0DATADONE_Msk | USBD_INTEN_ENDEPIN0_Msk | + USBD_INTEN_ENDEPOUT0_Msk; tu_varclr(&_dcd); _dcd.xfer[0][TUSB_DIR_IN].mps = MAX_PACKET_SIZE; _dcd.xfer[0][TUSB_DIR_OUT].mps = MAX_PACKET_SIZE; } -void dcd_int_handler(uint8_t rhport) -{ +void dcd_int_handler(uint8_t rhport) { (void) rhport; - uint32_t const inten = NRF_USBD->INTEN; + uint32_t const inten = NRF_USBD->INTEN; uint32_t int_status = 0; volatile uint32_t* regevt = &NRF_USBD->EVENTS_USBRESET; - for(uint8_t i=0; iactual_len = NRF_USBD->ISOIN.AMOUNT; @@ -649,13 +583,11 @@ void dcd_int_handler(uint8_t rhport) xfer->iso_in_transfer_ready = true; } - if ( int_status & USBD_INTEN_SOF_Msk ) - { + if (int_status & USBD_INTEN_SOF_Msk) { bool iso_enabled = false; // ISOOUT: Transfer data gathered in previous frame from buffer to RAM - if (NRF_USBD->EPOUTEN & USBD_EPOUTEN_ISOOUT_Msk) - { + if (NRF_USBD->EPOUTEN & USBD_EPOUTEN_ISOOUT_Msk) { iso_enabled = true; // Transfer from endpoint to RAM only if data is not corrupted if ((int_status & USBD_INTEN_USBEVENT_Msk) == 0 || @@ -665,20 +597,17 @@ void dcd_int_handler(uint8_t rhport) } // ISOIN: Notify client that data was transferred - if (NRF_USBD->EPINEN & USBD_EPINEN_ISOIN_Msk) - { + if (NRF_USBD->EPINEN & USBD_EPINEN_ISOIN_Msk) { iso_enabled = true; xfer_td_t* xfer = get_td(EP_ISO_NUM, TUSB_DIR_IN); - if ( xfer->iso_in_transfer_ready ) - { + if (xfer->iso_in_transfer_ready) { xfer->iso_in_transfer_ready = false; dcd_event_xfer_complete(0, EP_ISO_NUM | TUSB_DIR_IN_MASK, xfer->actual_len, XFER_RESULT_SUCCESS, true); } } - if ( !iso_enabled ) - { + 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; @@ -687,16 +616,17 @@ void dcd_int_handler(uint8_t rhport) dcd_event_bus_signal(0, DCD_EVENT_SOF, true); } - if ( int_status & USBD_INTEN_USBEVENT_Msk ) - { + if (int_status & USBD_INTEN_USBEVENT_Msk) { TU_LOG(3, "EVENTCAUSE = 0x%04lX\r\n", NRF_USBD->EVENTCAUSE); - enum { EVT_CAUSE_MASK = USBD_EVENTCAUSE_SUSPEND_Msk | USBD_EVENTCAUSE_RESUME_Msk | USBD_EVENTCAUSE_USBWUALLOWED_Msk | USBD_EVENTCAUSE_ISOOUTCRC_Msk }; + enum { + EVT_CAUSE_MASK = USBD_EVENTCAUSE_SUSPEND_Msk | USBD_EVENTCAUSE_RESUME_Msk | USBD_EVENTCAUSE_USBWUALLOWED_Msk | + USBD_EVENTCAUSE_ISOOUTCRC_Msk + }; uint32_t const evt_cause = NRF_USBD->EVENTCAUSE & EVT_CAUSE_MASK; NRF_USBD->EVENTCAUSE = evt_cause; // clear interrupt - if ( evt_cause & USBD_EVENTCAUSE_SUSPEND_Msk ) - { + if (evt_cause & USBD_EVENTCAUSE_SUSPEND_Msk) { // Put controller into low power mode // Leave HFXO disable to application, since it may be used by other peripherals NRF_USBD->LOWPOWER = 1; @@ -704,8 +634,7 @@ void dcd_int_handler(uint8_t rhport) dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); } - if ( evt_cause & USBD_EVENTCAUSE_USBWUALLOWED_Msk ) - { + if (evt_cause & USBD_EVENTCAUSE_USBWUALLOWED_Msk) { // USB is out of low power mode, and wakeup is allowed // Initiate RESUME signal NRF_USBD->DPDMVALUE = USBD_DPDMVALUE_STATE_Resume; @@ -717,34 +646,29 @@ void dcd_int_handler(uint8_t rhport) NRF_USBD->INTENSET = USBD_INTENSET_SOF_Msk; } - if ( evt_cause & USBD_EVENTCAUSE_RESUME_Msk ) - { + if (evt_cause & USBD_EVENTCAUSE_RESUME_Msk) { dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); } } // Setup tokens are specific to the Control endpoint. - if ( int_status & USBD_INTEN_EP0SETUP_Msk ) - { - uint8_t const setup[8] = - { - NRF_USBD->BMREQUESTTYPE , NRF_USBD->BREQUEST, NRF_USBD->WVALUEL , NRF_USBD->WVALUEH, - NRF_USBD->WINDEXL , NRF_USBD->WINDEXH , NRF_USBD->WLENGTHL, NRF_USBD->WLENGTHH + if (int_status & USBD_INTEN_EP0SETUP_Msk) { + uint8_t const setup[8] = { + NRF_USBD->BMREQUESTTYPE, NRF_USBD->BREQUEST, NRF_USBD->WVALUEL, NRF_USBD->WVALUEH, + NRF_USBD->WINDEXL, NRF_USBD->WINDEXH, NRF_USBD->WLENGTHL, NRF_USBD->WLENGTHH }; // nrf5x hw auto handle set address, there is no need to inform usb stack - tusb_control_request_t const * request = (tusb_control_request_t const *) setup; + tusb_control_request_t const* request = (tusb_control_request_t const*) setup; - if ( !(TUSB_REQ_RCPT_DEVICE == request->bmRequestType_bit.recipient && - TUSB_REQ_TYPE_STANDARD == request->bmRequestType_bit.type && - TUSB_REQ_SET_ADDRESS == request->bRequest) ) - { + if (!(TUSB_REQ_RCPT_DEVICE == request->bmRequestType_bit.recipient && + TUSB_REQ_TYPE_STANDARD == request->bmRequestType_bit.type && + TUSB_REQ_SET_ADDRESS == request->bRequest)) { dcd_event_setup_received(0, setup, true); } } - if ( int_status & EDPT_END_ALL_MASK ) - { + if (int_status & EDPT_END_ALL_MASK) { // DMA complete move data from SRAM <-> Endpoint // Must before endpoint transfer handling edpt_dma_end(); @@ -786,30 +710,24 @@ void dcd_int_handler(uint8_t rhport) * len if Host decides to sent fewer bytes, it this case transaction is also * complete and next transfer is not initiated here like for CBI. */ - for(uint8_t epnum=0; epnumEPOUT[epnum].AMOUNT; - xfer->buffer += xact_len; + xfer->buffer += xact_len; xfer->actual_len += xact_len; // Transfer complete if transaction len < Max Packet Size or total len is transferred - if ( (epnum != EP_ISO_NUM) && (xact_len == xfer->mps) && (xfer->actual_len < xfer->total_len) ) - { - if ( epnum == 0 ) - { + if ((epnum != EP_ISO_NUM) && (xact_len == xfer->mps) && (xfer->actual_len < xfer->total_len)) { + if (epnum == 0) { // Accept next Control Out packet. TASKS_EP0RCVOUT also require EasyDMA edpt_dma_start(&NRF_USBD->TASKS_EP0RCVOUT); - }else - { + } else { // nRF auto accept next Bulk/Interrupt OUT packet // nothing to do } - }else - { + } else { TU_ASSERT(xfer->started,); xfer->total_len = xfer->actual_len; xfer->started = false; @@ -823,11 +741,11 @@ void dcd_int_handler(uint8_t rhport) } // Endpoint <-> Host ( In & OUT ) - if ( int_status & (USBD_INTEN_EPDATA_Msk | USBD_INTEN_EP0DATADONE_Msk) ) - { + if (int_status & (USBD_INTEN_EPDATA_Msk | USBD_INTEN_EP0DATADONE_Msk)) { uint32_t data_status = NRF_USBD->EPDATASTATUS; NRF_USBD->EPDATASTATUS = data_status; - __ISB(); __DSB(); + __ISB(); + __DSB(); // EP0DATADONE is set with either Control Out on IN Data // Since EPDATASTATUS cannot be used to determine whether it is control OUT or IN. @@ -836,22 +754,18 @@ void dcd_int_handler(uint8_t rhport) bool const is_control_out = (int_status & USBD_INTEN_EP0DATADONE_Msk) && !(NRF_USBD->BMREQUESTTYPE & TUSB_DIR_IN_MASK); // CBI In: Endpoint -> Host (transaction complete) - for(uint8_t epnum=0; epnumEPIN[epnum].AMOUNT; - xfer->buffer += xact_len; + xfer->buffer += xact_len; xfer->actual_len += xact_len; - if ( xfer->actual_len < xfer->total_len ) - { + if (xfer->actual_len < xfer->total_len) { // Start DMA to copy next data packet xact_in_dma(epnum); - } else - { + } else { // CBI IN complete dcd_event_xfer_complete(0, epnum | TUSB_DIR_IN_MASK, xfer->actual_len, XFER_RESULT_SUCCESS, true); } @@ -859,17 +773,13 @@ void dcd_int_handler(uint8_t rhport) } // CBI OUT: Host -> Endpoint - for(uint8_t epnum=0; epnumstarted && xfer->actual_len < xfer->total_len ) - { + if (xfer->started && xfer->actual_len < xfer->total_len) { xact_out_dma(epnum); - }else - { + } else { // Data overflow !!! Nah, nRF will auto accept next Bulk/Interrupt OUT packet // Mark this endpoint with data received xfer->data_received = true; @@ -893,27 +803,22 @@ void dcd_int_handler(uint8_t rhport) #define SD_MAGIC_NUMBER 0x51B1E5DB #endif -static inline bool is_sd_existed(void) -{ +TU_ATTR_ALWAYS_INLINE static inline bool is_sd_existed(void) { return *((uint32_t*)(SOFTDEVICE_INFO_STRUCT_ADDRESS+4)) == SD_MAGIC_NUMBER; } // check if SD is existed and enabled -static inline bool is_sd_enabled(void) -{ +TU_ATTR_ALWAYS_INLINE static inline bool is_sd_enabled(void) { if ( !is_sd_existed() ) return false; - uint8_t sd_en = false; (void) sd_softdevice_is_enabled(&sd_en); return sd_en; } #endif -static bool hfclk_running(void) -{ +static bool hfclk_running(void) { #ifdef SOFTDEVICE_PRESENT - if ( is_sd_enabled() ) - { + if ( is_sd_enabled() ) { uint32_t is_running = 0; (void) sd_clock_hfclk_is_running(&is_running); return (is_running ? true : false); @@ -927,19 +832,17 @@ static bool hfclk_running(void) #endif } -static void hfclk_enable(void) -{ +static void hfclk_enable(void) { #if CFG_TUSB_OS == OPT_OS_MYNEWT usb_clock_request(); return; #else // already running, nothing to do - if ( hfclk_running() ) return; + if (hfclk_running()) return; #ifdef SOFTDEVICE_PRESENT - if ( is_sd_enabled() ) - { + if ( is_sd_enabled() ) { (void)sd_clock_hfclk_request(); return; } @@ -955,16 +858,14 @@ static void hfclk_enable(void) #endif } -static void hfclk_disable(void) -{ +static void hfclk_disable(void) { #if CFG_TUSB_OS == OPT_OS_MYNEWT usb_clock_release(); return; #else #ifdef SOFTDEVICE_PRESENT - if ( is_sd_enabled() ) - { + if ( is_sd_enabled() ) { (void)sd_clock_hfclk_release(); return; } @@ -988,8 +889,7 @@ static void hfclk_disable(void) // Therefore this function must be called to handle USB power event by // - nrfx_power_usbevt_init() : if Softdevice is not used or enabled // - SoftDevice SOC event : if SD is used and enabled -void tusb_hal_nrf_power_event (uint32_t event) -{ +void tusb_hal_nrf_power_event(uint32_t event) { // Value is chosen to be as same as NRFX_POWER_USB_EVT_* in nrfx_power.h enum { USB_EVT_DETECTED = 0, @@ -998,50 +898,41 @@ void tusb_hal_nrf_power_event (uint32_t event) }; #if CFG_TUSB_DEBUG >= 2 - const char* const power_evt_str[] = { "Detected", "Removed", "Ready" }; + const char* const power_evt_str[] = {"Detected", "Removed", "Ready"}; TU_LOG(2, "Power USB event: %s\r\n", power_evt_str[event]); #endif - switch ( event ) - { + switch (event) { case USB_EVT_DETECTED: - if ( !NRF_USBD->ENABLE ) - { + if (!NRF_USBD->ENABLE) { // Prepare for receiving READY event: disable interrupt since we will blocking wait NRF_USBD->INTENCLR = USBD_INTEN_USBEVENT_Msk; NRF_USBD->EVENTCAUSE = USBD_EVENTCAUSE_READY_Msk; - __ISB(); __DSB(); // for sync + __ISB(); + __DSB(); // for sync #ifdef NRF52_SERIES // NRF53 does not need this errata // ERRATA 171, 187, 166 - if ( nrfx_usbd_errata_187() ) - { + if (nrfx_usbd_errata_187()) { // CRITICAL_REGION_ENTER(); - if ( *((volatile uint32_t *) (0x4006EC00)) == 0x00000000 ) - { - *((volatile uint32_t *) (0x4006EC00)) = 0x00009375; - *((volatile uint32_t *) (0x4006ED14)) = 0x00000003; - *((volatile uint32_t *) (0x4006EC00)) = 0x00009375; - } - else - { - *((volatile uint32_t *) (0x4006ED14)) = 0x00000003; + if (*((volatile uint32_t*) (0x4006EC00)) == 0x00000000) { + *((volatile uint32_t*) (0x4006EC00)) = 0x00009375; + *((volatile uint32_t*) (0x4006ED14)) = 0x00000003; + *((volatile uint32_t*) (0x4006EC00)) = 0x00009375; + } else { + *((volatile uint32_t*) (0x4006ED14)) = 0x00000003; } // CRITICAL_REGION_EXIT(); } - if ( nrfx_usbd_errata_171() ) - { + if (nrfx_usbd_errata_171()) { // CRITICAL_REGION_ENTER(); - if ( *((volatile uint32_t *) (0x4006EC00)) == 0x00000000 ) - { - *((volatile uint32_t *) (0x4006EC00)) = 0x00009375; - *((volatile uint32_t *) (0x4006EC14)) = 0x000000C0; - *((volatile uint32_t *) (0x4006EC00)) = 0x00009375; - } - else - { - *((volatile uint32_t *) (0x4006EC14)) = 0x000000C0; + if (*((volatile uint32_t*) (0x4006EC00)) == 0x00000000) { + *((volatile uint32_t*) (0x4006EC00)) = 0x00009375; + *((volatile uint32_t*) (0x4006EC14)) = 0x000000C0; + *((volatile uint32_t*) (0x4006EC00)) = 0x00009375; + } else { + *((volatile uint32_t*) (0x4006EC14)) = 0x000000C0; } // CRITICAL_REGION_EXIT(); } @@ -1049,64 +940,58 @@ void tusb_hal_nrf_power_event (uint32_t event) // Enable the peripheral (will cause Ready event) NRF_USBD->ENABLE = 1; - __ISB(); __DSB(); // for sync + __ISB(); + __DSB(); // for sync // Enable HFCLK hfclk_enable(); } - break; + break; case USB_EVT_READY: // Skip if pull-up is enabled and HCLK is already running. // Application probably call this more than necessary. - if ( NRF_USBD->USBPULLUP && hfclk_running() ) break; + if (NRF_USBD->USBPULLUP && hfclk_running()) break; // Waiting for USBD peripheral enabled - while ( !(USBD_EVENTCAUSE_READY_Msk & NRF_USBD->EVENTCAUSE) ) { } + while (!(USBD_EVENTCAUSE_READY_Msk & NRF_USBD->EVENTCAUSE)) {} NRF_USBD->EVENTCAUSE = USBD_EVENTCAUSE_READY_Msk; - __ISB(); __DSB(); // for sync + __ISB(); + __DSB(); // for sync #ifdef NRF52_SERIES - if ( nrfx_usbd_errata_171() ) - { + if (nrfx_usbd_errata_171()) { // CRITICAL_REGION_ENTER(); - if ( *((volatile uint32_t *) (0x4006EC00)) == 0x00000000 ) - { - *((volatile uint32_t *) (0x4006EC00)) = 0x00009375; - *((volatile uint32_t *) (0x4006EC14)) = 0x00000000; - *((volatile uint32_t *) (0x4006EC00)) = 0x00009375; - } - else - { - *((volatile uint32_t *) (0x4006EC14)) = 0x00000000; + if (*((volatile uint32_t*) (0x4006EC00)) == 0x00000000) { + *((volatile uint32_t*) (0x4006EC00)) = 0x00009375; + *((volatile uint32_t*) (0x4006EC14)) = 0x00000000; + *((volatile uint32_t*) (0x4006EC00)) = 0x00009375; + } else { + *((volatile uint32_t*) (0x4006EC14)) = 0x00000000; } // CRITICAL_REGION_EXIT(); } - if ( nrfx_usbd_errata_187() ) - { + if (nrfx_usbd_errata_187()) { // CRITICAL_REGION_ENTER(); - if ( *((volatile uint32_t *) (0x4006EC00)) == 0x00000000 ) - { - *((volatile uint32_t *) (0x4006EC00)) = 0x00009375; - *((volatile uint32_t *) (0x4006ED14)) = 0x00000000; - *((volatile uint32_t *) (0x4006EC00)) = 0x00009375; - } - else - { - *((volatile uint32_t *) (0x4006ED14)) = 0x00000000; + if (*((volatile uint32_t*) (0x4006EC00)) == 0x00000000) { + *((volatile uint32_t*) (0x4006EC00)) = 0x00009375; + *((volatile uint32_t*) (0x4006ED14)) = 0x00000000; + *((volatile uint32_t*) (0x4006EC00)) = 0x00009375; + } else { + *((volatile uint32_t*) (0x4006ED14)) = 0x00000000; } // CRITICAL_REGION_EXIT(); } - if ( nrfx_usbd_errata_166() ) - { - *((volatile uint32_t *) (NRF_USBD_BASE + 0x800)) = 0x7E3; - *((volatile uint32_t *) (NRF_USBD_BASE + 0x804)) = 0x40; + if (nrfx_usbd_errata_166()) { + *((volatile uint32_t*) (NRF_USBD_BASE + 0x800)) = 0x7E3; + *((volatile uint32_t*) (NRF_USBD_BASE + 0x804)) = 0x40; - __ISB(); __DSB(); + __ISB(); + __DSB(); } #endif @@ -1122,27 +1007,27 @@ void tusb_hal_nrf_power_event (uint32_t event) // Don't enable USBD interrupt yet, if dcd_init() did not finish yet // Interrupt will be enabled by tud_init(), when USB stack is ready // to handle interrupts. - if (tud_inited()) - { + if (tud_inited()) { NVIC_EnableIRQ(USBD_IRQn); } // Wait for HFCLK - while ( !hfclk_running() ) { } + while (!hfclk_running()) {} // Enable pull up NRF_USBD->USBPULLUP = 1; - __ISB(); __DSB(); // for sync - break; + __ISB(); + __DSB(); // for sync + break; case USB_EVT_REMOVED: - if ( NRF_USBD->ENABLE ) - { + if (NRF_USBD->ENABLE) { // Abort all transfers // Disable pull up NRF_USBD->USBPULLUP = 0; - __ISB(); __DSB(); // for sync + __ISB(); + __DSB(); // for sync // Disable Interrupt NVIC_DisableIRQ(USBD_IRQn); @@ -1151,15 +1036,17 @@ void tusb_hal_nrf_power_event (uint32_t event) NRF_USBD->INTENCLR = NRF_USBD->INTEN; NRF_USBD->ENABLE = 0; - __ISB(); __DSB(); // for sync + __ISB(); + __DSB(); // for sync hfclk_disable(); dcd_event_bus_signal(0, DCD_EVENT_UNPLUGGED, is_in_isr()); } - break; + break; - default: break; + default: + break; } } From 5ee008c9974621cd4930d2975040717e71c16b84 Mon Sep 17 00:00:00 2001 From: Rbb666 Date: Tue, 16 Apr 2024 13:22:53 +0800 Subject: [PATCH 314/454] [add]Add rtthread script support to better integrate into rtthread projects. --- SConscript | 11 ++ lib/rt-thread/SConscript | 42 +++++++ lib/rt-thread/port/msc_device_port.c | 171 +++++++++++++++++++++++++++ lib/rt-thread/tusb_config.h | 147 +++++++++++++++++++++++ lib/rt-thread/tusb_rt_thread_port.c | 81 +++++++++++++ 5 files changed, 452 insertions(+) create mode 100644 SConscript create mode 100644 lib/rt-thread/SConscript create mode 100644 lib/rt-thread/port/msc_device_port.c create mode 100644 lib/rt-thread/tusb_config.h create mode 100644 lib/rt-thread/tusb_rt_thread_port.c diff --git a/SConscript b/SConscript new file mode 100644 index 000000000..b5043f437 --- /dev/null +++ b/SConscript @@ -0,0 +1,11 @@ +# RT-Thread building script for bridge + +import os +from building import * + +objs = [] +cwd = GetCurrentDir() + +objs = objs + SConscript(cwd + '/lib/rt-thread/SConscript') + +Return('objs') diff --git a/lib/rt-thread/SConscript b/lib/rt-thread/SConscript new file mode 100644 index 000000000..14fbf5549 --- /dev/null +++ b/lib/rt-thread/SConscript @@ -0,0 +1,42 @@ +import rtconfig +from building import * + +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"] + +if GetDepend(["PKG_TINYUSB_DEVICE_MSC"]): + src += ["../../src/class/msc/msc_device.c", "port/msc_device_port.c"] + +LOCAL_CFLAGS = '' + +if rtconfig.PLATFORM == 'gcc' or rtconfig.PLATFORM == 'armclang': # GCC or Keil AC6 + LOCAL_CFLAGS += ' -std=c99' +elif rtconfig.PLATFORM == 'armcc': # Keil AC5 + LOCAL_CFLAGS += ' --c99 --gnu' + +group = DefineGroup('TinyUSB', src, depend = ['PKG_USING_TINYUSB'], CPPPATH = path, LOCAL_CFLAGS = LOCAL_CFLAGS) + +Return('group') diff --git a/lib/rt-thread/port/msc_device_port.c b/lib/rt-thread/port/msc_device_port.c new file mode 100644 index 000000000..6af3c4f61 --- /dev/null +++ b/lib/rt-thread/port/msc_device_port.c @@ -0,0 +1,171 @@ +/* + * 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. + */ +#ifdef __RTTHREAD__ +#include +#include + +#include +#include + +static bool ejected = false; +static rt_device_t flash_device; +static struct rt_device_blk_geometry blk_geom; + +#ifdef __CC_ARM +uint16_t __builtin_bswap16(uint16_t x) +{ + return (x << 8) | (x >> 8); +} +#endif + +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; + + const char vid[] = PKG_TINYUSB_DEVICE_MSC_VID; + const char pid[] = PKG_TINYUSB_DEVICE_MSC_PID; + const char rev[] = PKG_TINYUSB_DEVICE_MSC_REV; + + memcpy(vendor_id, vid, strlen(vid)); + memcpy(product_id, pid, strlen(pid)); + memcpy(product_rev, rev, strlen(rev)); +} + +bool tud_msc_test_unit_ready_cb(uint8_t lun) +{ + (void) lun; + + if (ejected) + { + tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x3a, 0x00); + return false; + } + + if (flash_device == NULL) + { + flash_device = rt_device_find(PKG_TINYUSB_DEVICE_MSC_NAME); + } + if (flash_device != NULL) + { + static uint8_t open_flg = 0; + if (!open_flg) + { + open_flg = 1; + rt_device_open(flash_device, 0); + } + + rt_device_control(flash_device, RT_DEVICE_CTRL_BLK_GETGEOME, &blk_geom); + return true; + } + + return false; +} + +void tud_msc_capacity_cb(uint8_t lun, uint32_t *block_count, uint16_t *block_size) +{ + (void) lun; + + *block_count = blk_geom.sector_count; + *block_size = blk_geom.bytes_per_sector; +} + +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) + { + ejected = false; + } else { + // unload disk storage + ejected = true; + } + } + + return true; +} + +int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void *buffer, uint32_t bufsize) +{ + (void) lun; + (void) offset; + (void) bufsize; + + return (int32_t) rt_device_read(flash_device, (rt_off_t) lba, buffer, 1) * blk_geom.bytes_per_sector; +} + +int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t *buffer, uint32_t bufsize) +{ + (void) lun; + (void) offset; + (void) bufsize; + + return (int32_t) rt_device_write(flash_device, (rt_off_t) lba, buffer, 1) * blk_geom.bytes_per_sector; +} + +int32_t tud_msc_scsi_cb(uint8_t lun, uint8_t const scsi_cmd[16], void *buffer, uint16_t bufsize) +{ + void const *response = NULL; + uint16_t resplen = 0; + + // most scsi handled is input + bool in_xfer = true; + + switch (scsi_cmd[0]) + { + case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL: + // Host is about to read/write etc ... better not to disconnect disk + resplen = 0; + break; + + 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; + } + + // return resplen must not larger than bufsize + if (resplen > bufsize) resplen = bufsize; + + if (response && (resplen > 0)) + { + if (in_xfer) + { + memcpy(buffer, response, resplen); + } else { + // SCSI output + } + } + + return resplen; +} +#endif /*__RTTHREAD__*/ diff --git a/lib/rt-thread/tusb_config.h b/lib/rt-thread/tusb_config.h new file mode 100644 index 000000000..8b145f3f7 --- /dev/null +++ b/lib/rt-thread/tusb_config.h @@ -0,0 +1,147 @@ +/* + * 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. + */ + +#ifndef _TUSB_CONFIG_H_ +#define _TUSB_CONFIG_H_ + +#ifdef __RTTHREAD__ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +//-------------------------------------------------------------------- +// COMMON CONFIGURATION +//-------------------------------------------------------------------- + +#if defined(SOC_SERIES_STM32F0) +#define CFG_TUSB_MCU OPT_MCU_STM32F0 +#elif defined(SOC_SERIES_STM32F1) +#define CFG_TUSB_MCU OPT_MCU_STM32F1 +#elif defined(SOC_SERIES_STM32F2) +#define CFG_TUSB_MCU OPT_MCU_STM32F2 +#elif defined(SOC_SERIES_STM32F3) +#define CFG_TUSB_MCU OPT_MCU_STM32F3 +#elif defined(SOC_SERIES_STM32F4) +#define CFG_TUSB_MCU OPT_MCU_STM32F4 +#elif defined(SOC_SERIES_STM32F7) +#define CFG_TUSB_MCU OPT_MCU_STM32F7 +#elif defined(SOC_SERIES_STM32H7) +#define CFG_TUSB_MCU OPT_MCU_STM32H7 +#elif defined(SOC_SERIES_STM32L0) +#define CFG_TUSB_MCU OPT_MCU_STM32L0 +#elif defined(SOC_SERIES_STM32L1) +#define CFG_TUSB_MCU OPT_MCU_STM32L1 +#elif defined(SOC_SERIES_STM32L4) +#define CFG_TUSB_MCU OPT_MCU_STM32L4 +#elif defined(SOC_NRF52840) +#define CFG_TUSB_MCU OPT_MCU_NRF5X +#elif defined(SOC_HPM6000) +#define CFG_TUSB_MCU OPT_MCU_HPM +#elif defined(SOC_RP2040) +#define CFG_TUSB_MCU OPT_MCU_RP2040 +#elif defined(SOC_FAMILY_RENESAS) +#define CFG_TUSB_MCU OPT_MCU_RAXXX +#else +#error "Not support for current MCU" +#endif + +#define CFG_TUSB_OS OPT_OS_RTTHREAD + +//-------------------------------------------------------------------- +// DEBUG CONFIGURATION +//-------------------------------------------------------------------- +#ifdef CFG_TUSB_DEBUG +#define CFG_TUSB_DEBUG_PRINTF rt_kprintf +#endif /* CFG_TUSB_DEBUG */ + +#ifndef BOARD_DEVICE_RHPORT_NUM +#define BOARD_DEVICE_RHPORT_NUM PKG_TINYUSB_RHPORT_NUM +#endif + +#ifndef BOARD_DEVICE_RHPORT_SPEED +#define BOARD_DEVICE_RHPORT_SPEED PKG_TINYUSB_DEVICE_PORT_SPEED +#endif + +#if BOARD_DEVICE_RHPORT_NUM == 0 +#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) +#elif BOARD_DEVICE_RHPORT_NUM == 1 +#define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) +#else + #error "Incorrect RHPort configuration" +#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_TUSB_MEM_SECTION +#define CFG_TUSB_MEM_SECTION rt_section(PKG_TINYUSB_MEM_SECTION) +#endif + +#ifndef CFG_TUSB_MEM_ALIGN +#define CFG_TUSB_MEM_ALIGN rt_align(PKG_TINYUSB_MEM_ALIGN) +#endif + +//-------------------------------------------------------------------- +// DEVICE CONFIGURATION +//-------------------------------------------------------------------- + +#ifndef CFG_TUD_ENDPOINT0_SIZE +#define CFG_TUD_ENDPOINT0_SIZE PKG_TINYUSB_EDPT0_SIZE +#endif + +// CDC FIFO size of TX and RX +#define CFG_TUD_CDC_RX_BUFSIZE PKG_TINYUSB_DEVICE_CDC_RX_BUFSIZE +#define CFG_TUD_CDC_TX_BUFSIZE PKG_TINYUSB_DEVICE_CDC_TX_BUFSIZE + +#define CFG_TUD_MSC_EP_BUFSIZE PKG_TINYUSB_DEVICE_MSC_EP_BUFSIZE + +#define CFG_TUD_HID_EP_BUFSIZE PKG_TINYUSB_DEVICE_HID_EP_BUFSIZE + +#ifndef PKG_TINYUSB_DEVICE_CDC_STRING +#define PKG_TINYUSB_DEVICE_CDC_STRING "" +#endif + +#ifndef PKG_TINYUSB_DEVICE_MSC_STRING +#define PKG_TINYUSB_DEVICE_MSC_STRING "" +#endif + +#ifndef PKG_TINYUSB_DEVICE_HID_STRING +#define PKG_TINYUSB_DEVICE_HID_STRING "" +#endif + + +#ifdef __cplusplus +} +#endif +#endif /*__RTTHREAD__*/ + +#endif /* _TUSB_CONFIG_H_ */ diff --git a/lib/rt-thread/tusb_rt_thread_port.c b/lib/rt-thread/tusb_rt_thread_port.c new file mode 100644 index 000000000..d33e3ac60 --- /dev/null +++ b/lib/rt-thread/tusb_rt_thread_port.c @@ -0,0 +1,81 @@ +/* + * 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. + */ +#ifdef __RTTHREAD__ +#include + +#define DBG_TAG "TinyUSB" +#define DBG_LVL DBG_INFO +#include +#include + +#ifndef RT_USING_HEAP +/* if there is not enable heap, we should use static thread and stack. */ +static rt_uint8_t tusb_stack[PKG_TINYUSB_STACK_SIZE]; +static struct rt_thread tusb_thread; +#endif /* RT_USING_HEAP */ + +extern int tusb_board_init(void); + +static void tusb_thread_entry(void *parameter) +{ + (void) parameter; + while (1) + { + tud_task(); + } +} + +static int init_tinyusb(void) +{ + rt_thread_t tid; + + tusb_board_init(); + tusb_init(); + +#ifdef RT_USING_HEAP + tid = rt_thread_create("tusb", tusb_thread_entry, RT_NULL, + PKG_TINYUSB_STACK_SIZE, + PKG_TINYUSB_THREAD_PRIORITY, 10); + if (tid == RT_NULL) +#else + rt_err_t result; + + tid = &tusb_thread; + result = rt_thread_init(tid, "tusb", tusb_thread_entry, RT_NULL, + tusb_stack, sizeof(tusb_stack), 4, 10); + if (result != RT_EOK) +#endif /* RT_USING_HEAP */ + { + LOG_E("Fail to create TinyUSB thread"); + return -1; + } + + rt_thread_startup(tid); + + return 0; +} +INIT_APP_EXPORT(init_tinyusb); +#endif /*__RTTHREAD__*/ From 7545c40003d5f143cd7cb21037e4dd63b882d7f7 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 16 Apr 2024 22:17:29 +0700 Subject: [PATCH 315/454] cmake detect toolchain based on -DCMAKE_C_COMPILER --- .../cmake/toolchain/arm_iar.cmake | 14 +++++++++++--- hw/bsp/family_support.cmake | 19 +++++++++++++++++-- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/examples/build_system/cmake/toolchain/arm_iar.cmake b/examples/build_system/cmake/toolchain/arm_iar.cmake index 1482624e5..c22685112 100644 --- a/examples/build_system/cmake/toolchain/arm_iar.cmake +++ b/examples/build_system/cmake/toolchain/arm_iar.cmake @@ -1,8 +1,16 @@ set(CMAKE_SYSTEM_NAME Generic) -set(CMAKE_C_COMPILER "iccarm") -set(CMAKE_CXX_COMPILER "iccarm") -set(CMAKE_ASM_COMPILER "iasmarm") +if (NOT DEFINED CMAKE_C_COMPILER) + set(CMAKE_C_COMPILER "iccarm") +endif() + +if (NOT DEFINED CMAKE_CXX_COMPILER) + set(CMAKE_CXX_COMPILER "iccarm") +endif() + +if (NOT DEFINED CMAKE_ASM_COMPILER) + set(CMAKE_ASM_COMPILER "iasmarm") +endif() set(CMAKE_SIZE "size" CACHE FILEPATH "") set(CMAKE_OBJCOPY "ielftool" CACHE FILEPATH "") diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index d4f355e0c..7f4dda172 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -6,12 +6,24 @@ include(CMakePrintHelpers) set(TOP "${CMAKE_CURRENT_LIST_DIR}/../..") get_filename_component(TOP ${TOP} ABSOLUTE) -# Default to gcc +#------------------------------------------------------------- +# Toolchain +# Can be changed via -DTOOLCHAIN=gcc|iar or -DCMAKE_C_COMPILER= +#------------------------------------------------------------- +if (DEFINED CMAKE_C_COMPILER) + string(FIND ${CMAKE_C_COMPILER} "iccarm" IS_IAR) + if (NOT IS_IAR EQUAL -1) + set(TOOLCHAIN iar) + endif () +endif () + if (NOT DEFINED TOOLCHAIN) set(TOOLCHAIN gcc) endif () -# FAMILY not defined, try to detect it from BOARD +#------------------------------------------------------------- +# FAMILY and BOARD +#------------------------------------------------------------- if (NOT DEFINED FAMILY) if (NOT DEFINED BOARD) message(FATAL_ERROR "You must set a FAMILY variable for the build (e.g. rp2040, espressif). @@ -74,6 +86,9 @@ set(WARNING_FLAGS_GNU set(WARNING_FLAGS_IAR "") +#------------------------------------------------------------- +# Functions +#------------------------------------------------------------- # Filter example based on only.txt and skip.txt function(family_filter RESULT DIR) From 632a00195569126959836b7950cd9a62e4bb2dde Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 17 Apr 2024 11:38:33 +0700 Subject: [PATCH 316/454] update cmake build --- .../cmake/toolchain/arm_gcc.cmake | 35 +----------- .../cmake/toolchain/arm_iar.cmake | 25 +-------- .../build_system/cmake/toolchain/common.cmake | 53 +++++++++++++++++++ .../cmake/toolchain/msp430_gcc.cmake | 39 +------------- .../cmake/toolchain/set_flags.cmake | 17 ------ 5 files changed, 57 insertions(+), 112 deletions(-) create mode 100644 examples/build_system/cmake/toolchain/common.cmake delete mode 100644 examples/build_system/cmake/toolchain/set_flags.cmake diff --git a/examples/build_system/cmake/toolchain/arm_gcc.cmake b/examples/build_system/cmake/toolchain/arm_gcc.cmake index d3fd5b557..d3d73c629 100644 --- a/examples/build_system/cmake/toolchain/arm_gcc.cmake +++ b/examples/build_system/cmake/toolchain/arm_gcc.cmake @@ -1,5 +1,3 @@ -set(CMAKE_SYSTEM_NAME Generic) - if (NOT DEFINED CMAKE_C_COMPILER) set(CMAKE_C_COMPILER "arm-none-eabi-gcc") endif () @@ -9,44 +7,15 @@ if (NOT DEFINED CMAKE_CXX_COMPILER) endif () set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) - set(CMAKE_SIZE "arm-none-eabi-size" CACHE FILEPATH "") set(CMAKE_OBJCOPY "arm-none-eabi-objcopy" CACHE FILEPATH "") set(CMAKE_OBJDUMP "arm-none-eabi-objdump" CACHE FILEPATH "") -set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE) +include(${CMAKE_CURRENT_LIST_DIR}/common.cmake) -# Look for includes and libraries only in the target system prefix. -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) - -# pass TOOLCHAIN_CPU to -set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES CMAKE_SYSTEM_PROCESSOR) - -include(${CMAKE_CURRENT_LIST_DIR}/../cpu/${CMAKE_SYSTEM_PROCESSOR}.cmake) - -# enable all possible warnings for building examples -list(APPEND TOOLCHAIN_COMMON_FLAGS - -fdata-sections - -ffunction-sections - -fsingle-precision-constant - -fno-strict-aliasing - ) - -list(APPEND TOOLCHAIN_EXE_LINKER_FLAGS - -Wl,--print-memory-usage - -Wl,--gc-sections - -Wl,--cref - ) - -include(${CMAKE_CURRENT_LIST_DIR}/set_flags.cmake) - -# try_compile is cmake test compiling its own example, -# pass -nostdlib to skip stdlib linking 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/cmake/toolchain/arm_iar.cmake b/examples/build_system/cmake/toolchain/arm_iar.cmake index c22685112..6d2219ca8 100644 --- a/examples/build_system/cmake/toolchain/arm_iar.cmake +++ b/examples/build_system/cmake/toolchain/arm_iar.cmake @@ -1,5 +1,3 @@ -set(CMAKE_SYSTEM_NAME Generic) - if (NOT DEFINED CMAKE_C_COMPILER) set(CMAKE_C_COMPILER "iccarm") endif() @@ -16,25 +14,4 @@ set(CMAKE_SIZE "size" CACHE FILEPATH "") set(CMAKE_OBJCOPY "ielftool" CACHE FILEPATH "") set(CMAKE_OBJDUMP "iefdumparm" CACHE FILEPATH "") -set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE) - -# Look for includes and libraries only in the target system prefix. -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) - -# pass TOOLCHAIN_CPU to -set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES CMAKE_SYSTEM_PROCESSOR) - -include(${CMAKE_CURRENT_LIST_DIR}/../cpu/${CMAKE_SYSTEM_PROCESSOR}.cmake) - -# enable all possible warnings for building examples -list(APPEND TOOLCHAIN_COMMON_FLAGS - ) - -list(APPEND TOOLCHAIN_EXE_LINKER_FLAGS - --diag_suppress=Li065 - ) - -include(${CMAKE_CURRENT_LIST_DIR}/set_flags.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/common.cmake) diff --git a/examples/build_system/cmake/toolchain/common.cmake b/examples/build_system/cmake/toolchain/common.cmake new file mode 100644 index 000000000..56ac3caf5 --- /dev/null +++ b/examples/build_system/cmake/toolchain/common.cmake @@ -0,0 +1,53 @@ +include(CMakePrintHelpers) + +# ---------------------------------------------------------------------------- +# Common +# ---------------------------------------------------------------------------- +set(CMAKE_SYSTEM_NAME Generic) +set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE) + +# Look for includes and libraries only in the target system prefix. +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + +# pass TOOLCHAIN_CPU to +set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES CMAKE_SYSTEM_PROCESSOR) +include(${CMAKE_CURRENT_LIST_DIR}/../cpu/${CMAKE_SYSTEM_PROCESSOR}.cmake) + +# ---------------------------------------------------------------------------- +# Compile flags +# ---------------------------------------------------------------------------- +if (TOOLCHAIN STREQUAL "gcc") + list(APPEND TOOLCHAIN_COMMON_FLAGS + -fdata-sections + -ffunction-sections + -fsingle-precision-constant + -fno-strict-aliasing + ) + list(APPEND TOOLCHAIN_EXE_LINKER_FLAGS + -Wl,--print-memory-usage + -Wl,--gc-sections + -Wl,--cref + ) +elseif (TOOLCHAIN STREQUAL "iar") + #list(APPEND TOOLCHAIN_COMMON_FLAGS) + list(APPEND TOOLCHAIN_EXE_LINKER_FLAGS + --diag_suppress=Li065 + ) +elseif (TOOLCHAIN STREQUAL "clang") + message(FATAL_ERROR "Clang not supported") +endif () + +# join the toolchain flags into a single string +list(JOIN TOOLCHAIN_COMMON_FLAGS " " TOOLCHAIN_COMMON_FLAGS) +foreach (LANG IN ITEMS C CXX ASM) + set(CMAKE_${LANG}_FLAGS_INIT ${TOOLCHAIN_COMMON_FLAGS}) + # optimization flags for LOG, LOGGER ? + #set(CMAKE_${LANG}_FLAGS_RELEASE_INIT "-Os") + #set(CMAKE_${LANG}_FLAGS_DEBUG_INIT "-O0") +endforeach () + +# Linker +list(JOIN TOOLCHAIN_EXE_LINKER_FLAGS " " CMAKE_EXE_LINKER_FLAGS_INIT) diff --git a/examples/build_system/cmake/toolchain/msp430_gcc.cmake b/examples/build_system/cmake/toolchain/msp430_gcc.cmake index 6291ce5a4..73368adba 100644 --- a/examples/build_system/cmake/toolchain/msp430_gcc.cmake +++ b/examples/build_system/cmake/toolchain/msp430_gcc.cmake @@ -1,5 +1,3 @@ -set(CMAKE_SYSTEM_NAME Generic) - if (NOT DEFINED CMAKE_C_COMPILER) set(CMAKE_C_COMPILER "msp430-elf-gcc") endif () @@ -14,39 +12,4 @@ set(CMAKE_SIZE "msp430-elf-size" CACHE FILEPATH "") set(CMAKE_OBJCOPY "msp430-elf-objcopy" CACHE FILEPATH "") set(CMAKE_OBJDUMP "msp430-elf-objdump" CACHE FILEPATH "") -set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE) - -# Look for includes and libraries only in the target system prefix. -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) - -# pass TOOLCHAIN_CPU to -set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES CMAKE_SYSTEM_PROCESSOR) - -include(${CMAKE_CURRENT_LIST_DIR}/../cpu/${CMAKE_SYSTEM_PROCESSOR}.cmake) - -# enable all possible warnings for building examples -list(APPEND TOOLCHAIN_COMMON_FLAGS - -fdata-sections - -ffunction-sections - -fsingle-precision-constant - -fno-strict-aliasing - ) - -list(APPEND TOOLCHAIN_EXE_LINKER_FLAGS - -Wl,--print-memory-usage - -Wl,--gc-sections - -Wl,--cref - ) - -include(${CMAKE_CURRENT_LIST_DIR}/set_flags.cmake) - -# try_compile is cmake test compiling its own example, -# pass -nostdlib to skip stdlib linking -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") -endif () +include(${CMAKE_CURRENT_LIST_DIR}/common.cmake) diff --git a/examples/build_system/cmake/toolchain/set_flags.cmake b/examples/build_system/cmake/toolchain/set_flags.cmake deleted file mode 100644 index 44930ef4d..000000000 --- a/examples/build_system/cmake/toolchain/set_flags.cmake +++ /dev/null @@ -1,17 +0,0 @@ -include(CMakePrintHelpers) - -# join the toolchain flags into a single string -list(JOIN TOOLCHAIN_COMMON_FLAGS " " TOOLCHAIN_COMMON_FLAGS) - -foreach (LANG IN ITEMS C CXX ASM) - set(CMAKE_${LANG}_FLAGS_INIT ${TOOLCHAIN_COMMON_FLAGS}) - - #cmake_print_variables(CMAKE_${LANG}_FLAGS_INIT) - - # optimization flags for LOG, LOGGER ? - #set(CMAKE_${LANG}_FLAGS_RELEASE_INIT "-Os") - #set(CMAKE_${LANG}_FLAGS_DEBUG_INIT "-O0") -endforeach () - -# Linker -list(JOIN TOOLCHAIN_EXE_LINKER_FLAGS " " CMAKE_EXE_LINKER_FLAGS_INIT) From 9f0e4c28898996bf60ad34865fa5e7cf1d3bd04d Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 17 Apr 2024 12:58:16 +0700 Subject: [PATCH 317/454] run config update --- .idea/runConfigurations/kl25.xml | 4 ++-- .idea/runConfigurations/lpc1857.xml | 4 ++-- .idea/runConfigurations/lpc4088.xml | 4 ++-- .idea/runConfigurations/lpc54628.xml | 4 ++-- .idea/runConfigurations/lpc55s69.xml | 4 ++-- .idea/runConfigurations/mcx947.xml | 4 ++-- .idea/runConfigurations/nrf52840.xml | 4 ++-- .idea/runConfigurations/nrf5340.xml | 2 +- .idea/runConfigurations/ra4m1.xml | 2 +- .idea/runConfigurations/ra6m1.xml | 2 +- .idea/runConfigurations/ra6m5.xml | 2 +- .idea/runConfigurations/rt1010.xml | 2 +- .idea/runConfigurations/rt1060.xml | 4 ++-- .idea/runConfigurations/samd21g18.xml | 4 ++-- .idea/runConfigurations/samd51j19.xml | 4 ++-- .idea/runConfigurations/stlink.xml | 2 +- .idea/runConfigurations/stm32g474.xml | 4 ++-- .idea/runConfigurations/uno_r4.xml | 4 ++-- 18 files changed, 30 insertions(+), 30 deletions(-) diff --git a/.idea/runConfigurations/kl25.xml b/.idea/runConfigurations/kl25.xml index 5aace3a60..5c7bd73ba 100644 --- a/.idea/runConfigurations/kl25.xml +++ b/.idea/runConfigurations/kl25.xml @@ -1,6 +1,6 @@ - - + + diff --git a/.idea/runConfigurations/lpc1857.xml b/.idea/runConfigurations/lpc1857.xml index a60b481eb..2c059206e 100644 --- a/.idea/runConfigurations/lpc1857.xml +++ b/.idea/runConfigurations/lpc1857.xml @@ -1,6 +1,6 @@ - - + + diff --git a/.idea/runConfigurations/lpc4088.xml b/.idea/runConfigurations/lpc4088.xml index 767d98602..524279eaa 100644 --- a/.idea/runConfigurations/lpc4088.xml +++ b/.idea/runConfigurations/lpc4088.xml @@ -1,6 +1,6 @@ - - + + diff --git a/.idea/runConfigurations/lpc54628.xml b/.idea/runConfigurations/lpc54628.xml index e425e2387..f4ea323d7 100644 --- a/.idea/runConfigurations/lpc54628.xml +++ b/.idea/runConfigurations/lpc54628.xml @@ -1,6 +1,6 @@ - - + + diff --git a/.idea/runConfigurations/lpc55s69.xml b/.idea/runConfigurations/lpc55s69.xml index 27743d980..8a2cc00a7 100644 --- a/.idea/runConfigurations/lpc55s69.xml +++ b/.idea/runConfigurations/lpc55s69.xml @@ -1,6 +1,6 @@ - - + + diff --git a/.idea/runConfigurations/mcx947.xml b/.idea/runConfigurations/mcx947.xml index 2ff405739..528e5b644 100644 --- a/.idea/runConfigurations/mcx947.xml +++ b/.idea/runConfigurations/mcx947.xml @@ -1,6 +1,6 @@ - - + + diff --git a/.idea/runConfigurations/nrf52840.xml b/.idea/runConfigurations/nrf52840.xml index 8053d9b38..e24651de9 100644 --- a/.idea/runConfigurations/nrf52840.xml +++ b/.idea/runConfigurations/nrf52840.xml @@ -1,6 +1,6 @@ - - + + diff --git a/.idea/runConfigurations/nrf5340.xml b/.idea/runConfigurations/nrf5340.xml index 4a5a91734..56cad71b1 100644 --- a/.idea/runConfigurations/nrf5340.xml +++ b/.idea/runConfigurations/nrf5340.xml @@ -1,5 +1,5 @@ - + diff --git a/.idea/runConfigurations/ra4m1.xml b/.idea/runConfigurations/ra4m1.xml index a5c361a2a..83a2efe56 100644 --- a/.idea/runConfigurations/ra4m1.xml +++ b/.idea/runConfigurations/ra4m1.xml @@ -1,5 +1,5 @@ - + diff --git a/.idea/runConfigurations/ra6m1.xml b/.idea/runConfigurations/ra6m1.xml index 7db8e9815..c30757ed8 100644 --- a/.idea/runConfigurations/ra6m1.xml +++ b/.idea/runConfigurations/ra6m1.xml @@ -1,5 +1,5 @@ - + diff --git a/.idea/runConfigurations/ra6m5.xml b/.idea/runConfigurations/ra6m5.xml index 24e942fda..e252debbb 100644 --- a/.idea/runConfigurations/ra6m5.xml +++ b/.idea/runConfigurations/ra6m5.xml @@ -1,5 +1,5 @@ - + diff --git a/.idea/runConfigurations/rt1010.xml b/.idea/runConfigurations/rt1010.xml index 7929d56d8..f3c73929d 100644 --- a/.idea/runConfigurations/rt1010.xml +++ b/.idea/runConfigurations/rt1010.xml @@ -1,5 +1,5 @@ - + diff --git a/.idea/runConfigurations/rt1060.xml b/.idea/runConfigurations/rt1060.xml index f26dc7373..191523cbb 100644 --- a/.idea/runConfigurations/rt1060.xml +++ b/.idea/runConfigurations/rt1060.xml @@ -1,6 +1,6 @@ - - + + diff --git a/.idea/runConfigurations/samd21g18.xml b/.idea/runConfigurations/samd21g18.xml index a922da648..1baac68f1 100644 --- a/.idea/runConfigurations/samd21g18.xml +++ b/.idea/runConfigurations/samd21g18.xml @@ -1,6 +1,6 @@ - - + + diff --git a/.idea/runConfigurations/samd51j19.xml b/.idea/runConfigurations/samd51j19.xml index a11baa3fd..4cf88bad0 100644 --- a/.idea/runConfigurations/samd51j19.xml +++ b/.idea/runConfigurations/samd51j19.xml @@ -1,6 +1,6 @@ - - + + diff --git a/.idea/runConfigurations/stlink.xml b/.idea/runConfigurations/stlink.xml index c82f37d59..fa2d8bfca 100644 --- a/.idea/runConfigurations/stlink.xml +++ b/.idea/runConfigurations/stlink.xml @@ -1,5 +1,5 @@ - + diff --git a/.idea/runConfigurations/stm32g474.xml b/.idea/runConfigurations/stm32g474.xml index ad6209bc0..928c8fbeb 100644 --- a/.idea/runConfigurations/stm32g474.xml +++ b/.idea/runConfigurations/stm32g474.xml @@ -1,6 +1,6 @@ - - + + diff --git a/.idea/runConfigurations/uno_r4.xml b/.idea/runConfigurations/uno_r4.xml index f3d1ccac6..7e75e39cd 100644 --- a/.idea/runConfigurations/uno_r4.xml +++ b/.idea/runConfigurations/uno_r4.xml @@ -1,6 +1,6 @@ - - + + From 96f7ca02bff64021b14ed84544df873a0d694a79 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 17 Apr 2024 13:00:07 +0700 Subject: [PATCH 318/454] clang build board test with h743 --- .../build_system/cmake/cpu/cortex-m7.cmake | 11 ++++++++-- .../cmake/toolchain/arm_clang.cmake | 21 +++++++++++++++++++ .../build_system/cmake/toolchain/common.cmake | 11 +++++++++- hw/bsp/family_support.cmake | 9 ++++++++ hw/bsp/stm32h7/family.cmake | 5 +++++ 5 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 examples/build_system/cmake/toolchain/arm_clang.cmake diff --git a/examples/build_system/cmake/cpu/cortex-m7.cmake b/examples/build_system/cmake/cpu/cortex-m7.cmake index 3e5f7f44b..f7684af84 100644 --- a/examples/build_system/cmake/cpu/cortex-m7.cmake +++ b/examples/build_system/cmake/cpu/cortex-m7.cmake @@ -5,7 +5,6 @@ if (TOOLCHAIN STREQUAL "gcc") -mfloat-abi=hard -mfpu=fpv5-d16 ) - set(FREERTOS_PORT GCC_ARM_CM7 CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "iar") @@ -13,7 +12,15 @@ elseif (TOOLCHAIN STREQUAL "iar") --cpu cortex-m7 --fpu VFPv5_D16 ) - set(FREERTOS_PORT IAR_ARM_CM7 CACHE INTERNAL "") +elseif (TOOLCHAIN STREQUAL "clang") + set(TOOLCHAIN_COMMON_FLAGS + --target=arm-none-eabi + -mcpu=cortex-m7 + -mfloat-abi=hard + -mfpu=fpv5-d16 + ) + set(FREERTOS_PORT GCC_ARM_CM7 CACHE INTERNAL "") + endif () diff --git a/examples/build_system/cmake/toolchain/arm_clang.cmake b/examples/build_system/cmake/toolchain/arm_clang.cmake new file mode 100644 index 000000000..754d672fd --- /dev/null +++ b/examples/build_system/cmake/toolchain/arm_clang.cmake @@ -0,0 +1,21 @@ +if (NOT DEFINED CMAKE_C_COMPILER) + set(CMAKE_C_COMPILER "clang") +endif () + +if (NOT DEFINED CMAKE_CXX_COMPILER) + set(CMAKE_CXX_COMPILER "clang++") +endif () + +set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) +set(CMAKE_SIZE "llvm-size" CACHE FILEPATH "") +set(CMAKE_OBJCOPY "llvm-objcopy" CACHE FILEPATH "") +set(CMAKE_OBJDUMP "llvm-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/cmake/toolchain/common.cmake b/examples/build_system/cmake/toolchain/common.cmake index 56ac3caf5..6c6d54c74 100644 --- a/examples/build_system/cmake/toolchain/common.cmake +++ b/examples/build_system/cmake/toolchain/common.cmake @@ -37,7 +37,16 @@ elseif (TOOLCHAIN STREQUAL "iar") --diag_suppress=Li065 ) elseif (TOOLCHAIN STREQUAL "clang") - message(FATAL_ERROR "Clang not supported") + list(APPEND TOOLCHAIN_COMMON_FLAGS + -fdata-sections + -ffunction-sections + -fno-strict-aliasing + ) + list(APPEND TOOLCHAIN_EXE_LINKER_FLAGS + -Wl,--print-memory-usage + -Wl,--gc-sections + -Wl,--cref + ) endif () # join the toolchain flags into a single string diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index 7f4dda172..8dd61b91c 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -10,13 +10,22 @@ get_filename_component(TOP ${TOP} ABSOLUTE) # Toolchain # Can be changed via -DTOOLCHAIN=gcc|iar or -DCMAKE_C_COMPILER= #------------------------------------------------------------- +# Detect toolchain based on CMAKE_C_COMPILER if (DEFINED CMAKE_C_COMPILER) string(FIND ${CMAKE_C_COMPILER} "iccarm" IS_IAR) + string(FIND ${CMAKE_C_COMPILER} "clang" IS_CLANG) + string(FIND ${CMAKE_C_COMPILER} "gcc" IS_GCC) + if (NOT IS_IAR EQUAL -1) set(TOOLCHAIN iar) + elseif (NOT IS_CLANG EQUAL -1) + set(TOOLCHAIN clang) + elseif (NOT IS_GCC EQUAL -1) + set(TOOLCHAIN gcc) endif () endif () +# default to gcc if (NOT DEFINED TOOLCHAIN) set(TOOLCHAIN gcc) endif () diff --git a/hw/bsp/stm32h7/family.cmake b/hw/bsp/stm32h7/family.cmake index 6174dfda3..d852ce21c 100644 --- a/hw/bsp/stm32h7/family.cmake +++ b/hw/bsp/stm32h7/family.cmake @@ -29,6 +29,7 @@ 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) if(NOT DEFINED LD_FILE_IAR) @@ -72,6 +73,10 @@ function(add_board_target BOARD_TARGET) target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + ) endif () endif () endfunction() From 3442a87d5b52112a8bc4672322d488703e4ee23e Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 17 Apr 2024 20:06:13 +0700 Subject: [PATCH 319/454] - clang h743 build and run cdc_msc ok - switch unit test back to gcc, since path to clang conflict on local setup (x86 and arm) --- .../build_system/cmake/cpu/cortex-m7.cmake | 1 - .../build_system/cmake/toolchain/common.cmake | 2 +- hw/bsp/board.c | 19 +++++++++++++++++++ hw/bsp/stm32h7/family.cmake | 7 +++---- src/common/tusb_common.h | 1 + src/portable/synopsys/dwc2/dcd_dwc2.c | 6 +++--- test/unit-test/project.yml | 12 ++++++------ 7 files changed, 33 insertions(+), 15 deletions(-) diff --git a/examples/build_system/cmake/cpu/cortex-m7.cmake b/examples/build_system/cmake/cpu/cortex-m7.cmake index f7684af84..b0f84b76b 100644 --- a/examples/build_system/cmake/cpu/cortex-m7.cmake +++ b/examples/build_system/cmake/cpu/cortex-m7.cmake @@ -18,7 +18,6 @@ elseif (TOOLCHAIN STREQUAL "clang") set(TOOLCHAIN_COMMON_FLAGS --target=arm-none-eabi -mcpu=cortex-m7 - -mfloat-abi=hard -mfpu=fpv5-d16 ) set(FREERTOS_PORT GCC_ARM_CM7 CACHE INTERNAL "") diff --git a/examples/build_system/cmake/toolchain/common.cmake b/examples/build_system/cmake/toolchain/common.cmake index 6c6d54c74..bbd670b65 100644 --- a/examples/build_system/cmake/toolchain/common.cmake +++ b/examples/build_system/cmake/toolchain/common.cmake @@ -45,7 +45,7 @@ elseif (TOOLCHAIN STREQUAL "clang") list(APPEND TOOLCHAIN_EXE_LINKER_FLAGS -Wl,--print-memory-usage -Wl,--gc-sections - -Wl,--cref + #-Wl,--cref ) endif () diff --git a/hw/bsp/board.c b/hw/bsp/board.c index 23b4b6628..996ac9263 100644 --- a/hw/bsp/board.c +++ b/hw/bsp/board.c @@ -108,6 +108,25 @@ TU_ATTR_USED int sys_read (int fhdl, char *buf, size_t count) { // st->st_mode = S_IFCHR; //} +// Clang use picolibc +#if defined(__clang__) +static int cl_putc(char c, FILE *f) { + (void) f; + return sys_write(0, &c, 1); +} + +static int cl_getc(FILE* f) { + (void) f; + char c; + return sys_read(0, &c, 1) > 0 ? c : -1; +} + +static FILE __stdio = FDEV_SETUP_STREAM(cl_putc, cl_getc, NULL, _FDEV_SETUP_RW); +FILE *const stdin = &__stdio; +__strong_reference(stdin, stdout); +__strong_reference(stdin, stderr); +#endif + int board_getchar(void) { char c; return (sys_read(0, &c, 1) > 0) ? (int) c : (-1); diff --git a/hw/bsp/stm32h7/family.cmake b/hw/bsp/stm32h7/family.cmake index d852ce21c..ab9ba3fbb 100644 --- a/hw/bsp/stm32h7/family.cmake +++ b/hw/bsp/stm32h7/family.cmake @@ -56,10 +56,8 @@ function(add_board_target BOARD_TARGET) ${ST_CMSIS}/Include ${ST_HAL_DRIVER}/Inc ) - target_compile_options(${BOARD_TARGET} PUBLIC - ) - target_compile_definitions(${BOARD_TARGET} PUBLIC - ) + #target_compile_options(${BOARD_TARGET} PUBLIC) + #target_compile_definitions(${BOARD_TARGET} PUBLIC) update_board(${BOARD_TARGET}) @@ -75,6 +73,7 @@ function(add_board_target BOARD_TARGET) ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${BOARD_TARGET} PUBLIC + #-ldummyhost "LINKER:--script=${LD_FILE_GNU}" ) endif () diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index 1f08ce4ed..0d4082c03 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -65,6 +65,7 @@ // Standard Headers #include #include +#include #include #include #include diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index a824226c7..f17d30f06 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -174,7 +174,7 @@ static bool fifo_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t packet_size) { // 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 %lu", fifo_size * 4, + TU_LOG(DWC2_DEBUG, " Allocated %u bytes at offset %" PRIu32, fifo_size * 4, _dwc2_controller[rhport].ep_fifo_size - _allocated_fifo_words_tx * 4); // DIEPTXF starts at FIFO #1. @@ -419,9 +419,9 @@ void print_dwc2_info(dwc2_regs_t* dwc2) { 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%08lX, ", p[i]); + TU_LOG(DWC2_DEBUG, "0x%08" PRIX32 ", ", p[i]); } - TU_LOG(DWC2_DEBUG, "0x%08lX\r\n", p[5]); + TU_LOG(DWC2_DEBUG, "0x%08" PRIX32 "\r\n", p[5]); } #endif diff --git a/test/unit-test/project.yml b/test/unit-test/project.yml index 82528f68c..7fbbabfe6 100644 --- a/test/unit-test/project.yml +++ b/test/unit-test/project.yml @@ -81,20 +81,20 @@ :tools: :test_compiler: - :executable: clang - :name: 'clang compiler' + :executable: gcc + :name: 'gcc compiler' :arguments: - -I"$": COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE #expands to -I search paths - -I"$": COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR #expands to -I search paths - -D$: COLLECTION_DEFINES_TEST_AND_VENDOR #expands to all -D defined symbols - - -fsanitize=address + #- -fsanitize=address - -c ${1} #source code input file (Ruby method call param list sub) - -o ${2} #object file output (Ruby method call param list sub) :test_linker: - :executable: clang - :name: 'clang linker' + :executable: gcc + :name: 'gcc linker' :arguments: - - -fsanitize=address + #- -fsanitize=address - ${1} #list of object files to link (Ruby method call param list sub) - -o ${2} #executable file output (Ruby method call param list sub) From 982713ad476f42ccb9786e40417d91ac11cb46be Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 17 Apr 2024 21:51:10 +0700 Subject: [PATCH 320/454] add clang to ci build --- .github/workflows/cmake_arm.yml | 93 +++++++++++++++++++++++++++++---- 1 file changed, 82 insertions(+), 11 deletions(-) diff --git a/.github/workflows/cmake_arm.yml b/.github/workflows/cmake_arm.yml index 1e5f61e0e..52aaa71e8 100644 --- a/.github/workflows/cmake_arm.yml +++ b/.github/workflows/cmake_arm.yml @@ -28,9 +28,9 @@ concurrency: jobs: # --------------------------------------- - # Build ARM family + # Build ARM with GCC # --------------------------------------- - build-arm: + arm-gcc: runs-on: ubuntu-latest strategy: fail-fast: false @@ -68,9 +68,6 @@ jobs: with: release: '11.2-2022.02' - - name: Install Ninja - run: sudo apt install -y ninja-build - - name: Checkout TinyUSB uses: actions/checkout@v4 @@ -82,13 +79,12 @@ jobs: ref: develop path: pico-sdk - - name: Get Dependencies - run: python3 tools/get_deps.py ${{ matrix.family }} - - name: Build - run: python tools/build_cmake.py ${{ matrix.family }} -DCMAKE_BUILD_TYPE=MinSizeRel + run: | + sudo apt install -y ninja-build + python3 tools/get_deps.py ${{ matrix.family }} + python tools/build_cmake.py ${{ matrix.family }} -DCMAKE_BUILD_TYPE=MinSizeRel env: - # for rp2040, there is no harm if defined for other families PICO_SDK_PATH: ${{ github.workspace }}/pico-sdk - name: Upload Artifacts for Hardware Testing (rp2040) @@ -115,6 +111,81 @@ jobs: path: | cmake-build/cmake-build-itsybitsy_m4/*/*/*.bin + # --------------------------------------- + # Build ARM with Clang + # --------------------------------------- + arm-clang: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + family: + # Alphabetical order + - 'imxrt' + - 'kinetis_k kinetis_kl' + - 'lpc17 lpc18 lpc40 lpc43' + - 'lpc54 lpc55' + - 'mcx' + - 'nrf' + - 'ra' + - 'rp2040' + - 'samd21' + - 'samd51' + - 'stm32f0' + - 'stm32f1' + - 'stm32f4' + - 'stm32f7' + - 'stm32g0' + - 'stm32g4' + - 'stm32h5' + - 'stm32h7' + - 'stm32l4' + - 'stm32u5' + 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/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@v3 + 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: Set Toolchain Path + run: echo >> $GITHUB_PATH `echo ~/cache/toolchain/*/bin` + + - 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: Build + run: | + sudo apt install -y ninja-build + python3 tools/get_deps.py ${{ matrix.family }} + python tools/build_cmake.py ${{ matrix.family }} -DCMAKE_BUILD_TYPE=MinSizeRel + env: + PICO_SDK_PATH: ${{ github.workspace }}/pico-sdk + # --------------------------------------- # Hardware in the loop (HIL) # Current self-hosted instance is running on an RPI4. For attached hardware checkout hil_pi4.json @@ -122,7 +193,7 @@ jobs: hil-test: # run only with hathach's commit due to limited resource on RPI4 if: github.repository_owner == 'hathach' - needs: build-arm + needs: arm-gcc runs-on: [self-hosted, rp2040, nrf52840, hardware-in-the-loop] strategy: fail-fast: false From 5ca68ec049c56cd04db8fde2c9fb50f19a4e9263 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 17 Apr 2024 22:13:01 +0700 Subject: [PATCH 321/454] forgot to specify clang --- .github/workflows/cmake_arm.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cmake_arm.yml b/.github/workflows/cmake_arm.yml index 52aaa71e8..0c584eb9a 100644 --- a/.github/workflows/cmake_arm.yml +++ b/.github/workflows/cmake_arm.yml @@ -182,7 +182,7 @@ jobs: run: | sudo apt install -y ninja-build python3 tools/get_deps.py ${{ matrix.family }} - python tools/build_cmake.py ${{ matrix.family }} -DCMAKE_BUILD_TYPE=MinSizeRel + python tools/build_cmake.py ${{ matrix.family }} -DTOOLCHAIN=clang -DCMAKE_BUILD_TYPE=MinSizeRel env: PICO_SDK_PATH: ${{ github.workspace }}/pico-sdk From 824e39ddeb762a0876702304ac95ea3b1d40cb5a Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 17 Apr 2024 23:08:06 +0700 Subject: [PATCH 322/454] more clang update --- examples/build_system/cmake/cpu/cortex-m0.cmake | 5 +++-- .../build_system/cmake/cpu/cortex-m0plus.cmake | 5 +++-- examples/build_system/cmake/cpu/cortex-m23.cmake | 5 +++-- examples/build_system/cmake/cpu/cortex-m3.cmake | 5 +++-- .../cmake/cpu/cortex-m33-nodsp-nofp.cmake | 5 +++-- examples/build_system/cmake/cpu/cortex-m33.cmake | 5 +++-- examples/build_system/cmake/cpu/cortex-m4.cmake | 9 +++++++++ examples/build_system/cmake/cpu/cortex-m7.cmake | 16 ++++++++-------- examples/build_system/cmake/cpu/msp430.cmake | 3 +++ examples/device/cdc_msc/src/main.c | 4 ---- hw/bsp/board_api.h | 3 +++ hw/bsp/stm32h7/family.cmake | 9 ++++----- 12 files changed, 45 insertions(+), 29 deletions(-) diff --git a/examples/build_system/cmake/cpu/cortex-m0.cmake b/examples/build_system/cmake/cpu/cortex-m0.cmake index bc2257048..2438ca96a 100644 --- a/examples/build_system/cmake/cpu/cortex-m0.cmake +++ b/examples/build_system/cmake/cpu/cortex-m0.cmake @@ -4,14 +4,15 @@ if (TOOLCHAIN STREQUAL "gcc") -mcpu=cortex-m0plus -mfloat-abi=soft ) - set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") +elseif (TOOLCHAIN STREQUAL "clang") + message(FATAL_ERROR "Clang is not supported for this target") + elseif (TOOLCHAIN STREQUAL "iar") set(TOOLCHAIN_COMMON_FLAGS --cpu cortex-m0 ) - set(FREERTOS_PORT IAR_ARM_CM0 CACHE INTERNAL "") endif () diff --git a/examples/build_system/cmake/cpu/cortex-m0plus.cmake b/examples/build_system/cmake/cpu/cortex-m0plus.cmake index bc2257048..2438ca96a 100644 --- a/examples/build_system/cmake/cpu/cortex-m0plus.cmake +++ b/examples/build_system/cmake/cpu/cortex-m0plus.cmake @@ -4,14 +4,15 @@ if (TOOLCHAIN STREQUAL "gcc") -mcpu=cortex-m0plus -mfloat-abi=soft ) - set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") +elseif (TOOLCHAIN STREQUAL "clang") + message(FATAL_ERROR "Clang is not supported for this target") + elseif (TOOLCHAIN STREQUAL "iar") set(TOOLCHAIN_COMMON_FLAGS --cpu cortex-m0 ) - set(FREERTOS_PORT IAR_ARM_CM0 CACHE INTERNAL "") endif () diff --git a/examples/build_system/cmake/cpu/cortex-m23.cmake b/examples/build_system/cmake/cpu/cortex-m23.cmake index c7ce1d242..a7eb82684 100644 --- a/examples/build_system/cmake/cpu/cortex-m23.cmake +++ b/examples/build_system/cmake/cpu/cortex-m23.cmake @@ -4,14 +4,15 @@ if (TOOLCHAIN STREQUAL "gcc") -mcpu=cortex-m23 -mfloat-abi=soft ) - set(FREERTOS_PORT GCC_ARM_CM23_NTZ_NONSECURE CACHE INTERNAL "") +elseif (TOOLCHAIN STREQUAL "clang") + message(FATAL_ERROR "Clang is not supported for this target") + elseif (TOOLCHAIN STREQUAL "iar") set(TOOLCHAIN_COMMON_FLAGS --cpu cortex-m23 ) - set(FREERTOS_PORT IAR_ARM_CM23_NTZ_NONSECURE CACHE INTERNAL "") endif () diff --git a/examples/build_system/cmake/cpu/cortex-m3.cmake b/examples/build_system/cmake/cpu/cortex-m3.cmake index f6f5a62f8..90982f415 100644 --- a/examples/build_system/cmake/cpu/cortex-m3.cmake +++ b/examples/build_system/cmake/cpu/cortex-m3.cmake @@ -3,14 +3,15 @@ if (TOOLCHAIN STREQUAL "gcc") -mthumb -mcpu=cortex-m3 ) - set(FREERTOS_PORT GCC_ARM_CM3 CACHE INTERNAL "") +elseif (TOOLCHAIN STREQUAL "clang") + message(FATAL_ERROR "Clang is not supported for this target") + elseif (TOOLCHAIN STREQUAL "iar") set(TOOLCHAIN_COMMON_FLAGS --cpu cortex-m3 ) - set(FREERTOS_PORT IAR_ARM_CM3 CACHE INTERNAL "") endif () diff --git a/examples/build_system/cmake/cpu/cortex-m33-nodsp-nofp.cmake b/examples/build_system/cmake/cpu/cortex-m33-nodsp-nofp.cmake index 01e6b979a..51fd70b0e 100644 --- a/examples/build_system/cmake/cpu/cortex-m33-nodsp-nofp.cmake +++ b/examples/build_system/cmake/cpu/cortex-m33-nodsp-nofp.cmake @@ -4,14 +4,15 @@ if (TOOLCHAIN STREQUAL "gcc") -mcpu=cortex-m33+nodsp -mfloat-abi=soft ) - set(FREERTOS_PORT GCC_ARM_CM33_NTZ_NONSECURE CACHE INTERNAL "") +elseif (TOOLCHAIN STREQUAL "clang") + message(FATAL_ERROR "Clang is not supported for this target") + elseif (TOOLCHAIN STREQUAL "iar") set(TOOLCHAIN_COMMON_FLAGS --cpu cortex-m33+nodsp ) - set(FREERTOS_PORT IAR_ARM_CM33_NTZ_NONSECURE CACHE INTERNAL "") endif () diff --git a/examples/build_system/cmake/cpu/cortex-m33.cmake b/examples/build_system/cmake/cpu/cortex-m33.cmake index 94c29099d..c38d05376 100644 --- a/examples/build_system/cmake/cpu/cortex-m33.cmake +++ b/examples/build_system/cmake/cpu/cortex-m33.cmake @@ -5,15 +5,16 @@ if (TOOLCHAIN STREQUAL "gcc") -mfloat-abi=hard -mfpu=fpv5-sp-d16 ) - set(FREERTOS_PORT GCC_ARM_CM33_NTZ_NONSECURE CACHE INTERNAL "") +elseif (TOOLCHAIN STREQUAL "clang") + message(FATAL_ERROR "Clang is not supported for this target") + elseif (TOOLCHAIN STREQUAL "iar") set(TOOLCHAIN_COMMON_FLAGS --cpu cortex-m33 --fpu VFPv5-SP ) - set(FREERTOS_PORT IAR_ARM_CM33_NTZ_NONSECURE CACHE INTERNAL "") endif () diff --git a/examples/build_system/cmake/cpu/cortex-m4.cmake b/examples/build_system/cmake/cpu/cortex-m4.cmake index db308aa83..9cdadc6f8 100644 --- a/examples/build_system/cmake/cpu/cortex-m4.cmake +++ b/examples/build_system/cmake/cpu/cortex-m4.cmake @@ -5,7 +5,16 @@ if (TOOLCHAIN STREQUAL "gcc") -mfloat-abi=hard -mfpu=fpv4-sp-d16 ) + if (NOT DEFINED FREERTOS_PORT) + set(FREERTOS_PORT GCC_ARM_CM4F CACHE INTERNAL "") + endif () +elseif (TOOLCHAIN STREQUAL "clang") + set(TOOLCHAIN_COMMON_FLAGS + --target=arm-none-eabi + -mcpu=cortex-m4 + -mfpu=fpv4-sp-d16 + ) if (NOT DEFINED FREERTOS_PORT) set(FREERTOS_PORT GCC_ARM_CM4F CACHE INTERNAL "") endif () diff --git a/examples/build_system/cmake/cpu/cortex-m7.cmake b/examples/build_system/cmake/cpu/cortex-m7.cmake index b0f84b76b..b41dfded5 100644 --- a/examples/build_system/cmake/cpu/cortex-m7.cmake +++ b/examples/build_system/cmake/cpu/cortex-m7.cmake @@ -7,6 +7,14 @@ if (TOOLCHAIN STREQUAL "gcc") ) 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-d16 + ) + set(FREERTOS_PORT GCC_ARM_CM7 CACHE INTERNAL "") + elseif (TOOLCHAIN STREQUAL "iar") set(TOOLCHAIN_COMMON_FLAGS --cpu cortex-m7 @@ -14,12 +22,4 @@ elseif (TOOLCHAIN STREQUAL "iar") ) set(FREERTOS_PORT IAR_ARM_CM7 CACHE INTERNAL "") -elseif (TOOLCHAIN STREQUAL "clang") - set(TOOLCHAIN_COMMON_FLAGS - --target=arm-none-eabi - -mcpu=cortex-m7 - -mfpu=fpv5-d16 - ) - set(FREERTOS_PORT GCC_ARM_CM7 CACHE INTERNAL "") - endif () diff --git a/examples/build_system/cmake/cpu/msp430.cmake b/examples/build_system/cmake/cpu/msp430.cmake index b4b47a2e8..584ec5741 100644 --- a/examples/build_system/cmake/cpu/msp430.cmake +++ b/examples/build_system/cmake/cpu/msp430.cmake @@ -1,6 +1,9 @@ if (TOOLCHAIN STREQUAL "gcc") set(FREERTOS_PORT GCC_MSP430F449 CACHE INTERNAL "") +elseif (TOOLCHAIN STREQUAL "clang") + message(FATAL_ERROR "Clang is not supported for this target") + elseif (TOOLCHAIN STREQUAL "iar") set(FREERTOS_PORT IAR_MSP430 CACHE INTERNAL "") diff --git a/examples/device/cdc_msc/src/main.c b/examples/device/cdc_msc/src/main.c index 0d3f97c8f..4581a3bab 100644 --- a/examples/device/cdc_msc/src/main.c +++ b/examples/device/cdc_msc/src/main.c @@ -23,10 +23,6 @@ * */ -#include -#include -#include - #include "bsp/board_api.h" #include "tusb.h" diff --git a/hw/bsp/board_api.h b/hw/bsp/board_api.h index 3b9f211a2..418ce3551 100644 --- a/hw/bsp/board_api.h +++ b/hw/bsp/board_api.h @@ -32,7 +32,10 @@ extern "C" { #endif #include +#include #include +#include + #include "tusb.h" #if CFG_TUSB_OS == OPT_OS_FREERTOS diff --git a/hw/bsp/stm32h7/family.cmake b/hw/bsp/stm32h7/family.cmake index ab9ba3fbb..a4123dda7 100644 --- a/hw/bsp/stm32h7/family.cmake +++ b/hw/bsp/stm32h7/family.cmake @@ -67,15 +67,14 @@ function(add_board_target BOARD_TARGET) -nostartfiles --specs=nosys.specs --specs=nano.specs ) + 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}" ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") - target_link_options(${BOARD_TARGET} PUBLIC - #-ldummyhost - "LINKER:--script=${LD_FILE_GNU}" - ) endif () endif () endfunction() From be0d62ba6c84e6c44416f5a837d830000f316505 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 19 Apr 2024 13:40:42 +0700 Subject: [PATCH 323/454] clang samd51 compile but does not run, rom is correct, but ram is lacking bss. Got stkerr -> hardfault --- .../build_system/cmake/cpu/cortex-m0.cmake | 6 +++- .../build_system/cmake/cpu/cortex-m23.cmake | 6 +++- .../build_system/cmake/cpu/cortex-m3.cmake | 6 +++- .../build_system/cmake/cpu/cortex-m33.cmake | 7 ++++- .../build_system/cmake/toolchain/common.cmake | 4 ++- hw/bsp/family_support.cmake | 5 +-- hw/bsp/samd51/family.cmake | 31 +++++++++++-------- 7 files changed, 45 insertions(+), 20 deletions(-) diff --git a/examples/build_system/cmake/cpu/cortex-m0.cmake b/examples/build_system/cmake/cpu/cortex-m0.cmake index 2438ca96a..ddf0f16af 100644 --- a/examples/build_system/cmake/cpu/cortex-m0.cmake +++ b/examples/build_system/cmake/cpu/cortex-m0.cmake @@ -7,7 +7,11 @@ if (TOOLCHAIN STREQUAL "gcc") set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "clang") - message(FATAL_ERROR "Clang is not supported for this target") + set(TOOLCHAIN_COMMON_FLAGS + --target=arm-none-eabi + -mcpu=cortex-m0plus + ) + set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "iar") set(TOOLCHAIN_COMMON_FLAGS diff --git a/examples/build_system/cmake/cpu/cortex-m23.cmake b/examples/build_system/cmake/cpu/cortex-m23.cmake index a7eb82684..00382ed9b 100644 --- a/examples/build_system/cmake/cpu/cortex-m23.cmake +++ b/examples/build_system/cmake/cpu/cortex-m23.cmake @@ -7,7 +7,11 @@ if (TOOLCHAIN STREQUAL "gcc") set(FREERTOS_PORT GCC_ARM_CM23_NTZ_NONSECURE CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "clang") - message(FATAL_ERROR "Clang is not supported for this target") + set(TOOLCHAIN_COMMON_FLAGS + --target=arm-none-eabi + -mcpu=cortex-m23 + ) + set(FREERTOS_PORT GCC_ARM_CM23_NTZ_NONSECURE CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "iar") set(TOOLCHAIN_COMMON_FLAGS diff --git a/examples/build_system/cmake/cpu/cortex-m3.cmake b/examples/build_system/cmake/cpu/cortex-m3.cmake index 90982f415..27888604e 100644 --- a/examples/build_system/cmake/cpu/cortex-m3.cmake +++ b/examples/build_system/cmake/cpu/cortex-m3.cmake @@ -6,7 +6,11 @@ if (TOOLCHAIN STREQUAL "gcc") set(FREERTOS_PORT GCC_ARM_CM3 CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "clang") - message(FATAL_ERROR "Clang is not supported for this target") + set(TOOLCHAIN_COMMON_FLAGS + --target=arm-none-eabi + -mcpu=cortex-m3 + ) + set(FREERTOS_PORT GCC_ARM_CM3 CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "iar") set(TOOLCHAIN_COMMON_FLAGS diff --git a/examples/build_system/cmake/cpu/cortex-m33.cmake b/examples/build_system/cmake/cpu/cortex-m33.cmake index c38d05376..d56d07ebc 100644 --- a/examples/build_system/cmake/cpu/cortex-m33.cmake +++ b/examples/build_system/cmake/cpu/cortex-m33.cmake @@ -8,7 +8,12 @@ if (TOOLCHAIN STREQUAL "gcc") set(FREERTOS_PORT GCC_ARM_CM33_NTZ_NONSECURE CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "clang") - message(FATAL_ERROR "Clang is not supported for this target") + set(TOOLCHAIN_COMMON_FLAGS + --target=arm-none-eabi + -mcpu=cortex-m33 + -mfpu=fpv5-sp-d16 + ) + set(FREERTOS_PORT GCC_ARM_CM33_NTZ_NONSECURE CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "iar") set(TOOLCHAIN_COMMON_FLAGS diff --git a/examples/build_system/cmake/toolchain/common.cmake b/examples/build_system/cmake/toolchain/common.cmake index bbd670b65..688715914 100644 --- a/examples/build_system/cmake/toolchain/common.cmake +++ b/examples/build_system/cmake/toolchain/common.cmake @@ -31,11 +31,13 @@ if (TOOLCHAIN STREQUAL "gcc") -Wl,--gc-sections -Wl,--cref ) + elseif (TOOLCHAIN STREQUAL "iar") #list(APPEND TOOLCHAIN_COMMON_FLAGS) list(APPEND TOOLCHAIN_EXE_LINKER_FLAGS --diag_suppress=Li065 ) + elseif (TOOLCHAIN STREQUAL "clang") list(APPEND TOOLCHAIN_COMMON_FLAGS -fdata-sections @@ -45,7 +47,7 @@ elseif (TOOLCHAIN STREQUAL "clang") list(APPEND TOOLCHAIN_EXE_LINKER_FLAGS -Wl,--print-memory-usage -Wl,--gc-sections - #-Wl,--cref + -Wl,--cref ) endif () diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index 8dd61b91c..d86ecc0a2 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -219,8 +219,9 @@ function(family_configure_common TARGET RTOS) if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 12.0) target_link_options(${TARGET} PUBLIC "LINKER:--no-warn-rwx-segments") endif () - endif() - if (CMAKE_C_COMPILER_ID STREQUAL "IAR") + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${TARGET} PUBLIC "LINKER:-Map=$.map") + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${TARGET} PUBLIC "LINKER:--map=$.map") endif() diff --git a/hw/bsp/samd51/family.cmake b/hw/bsp/samd51/family.cmake index 4d91bf1a6..08f03f727 100644 --- a/hw/bsp/samd51/family.cmake +++ b/hw/bsp/samd51/family.cmake @@ -1,6 +1,7 @@ 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) @@ -18,6 +19,16 @@ set(OPENOCD_OPTION "-f interface/cmsis-dap.cfg -c \"transport select swd\" -c \" # only need to be built ONCE for all examples function(add_board_target BOARD_TARGET) if (NOT TARGET ${BOARD_TARGET}) + 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 () + + if (NOT DEFINED STARTUP_FILE_${CMAKE_C_COMPILER_ID}) + set(STARTUP_FILE_GNU ${SDK_DIR}/gcc/gcc/startup_samd51.c) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + endif () + add_library(${BOARD_TARGET} STATIC ${SDK_DIR}/gcc/system_samd51.c ${SDK_DIR}/hpl/gclk/hpl_gclk.c @@ -25,6 +36,7 @@ function(add_board_target BOARD_TARGET) ${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}/ @@ -34,29 +46,22 @@ function(add_board_target BOARD_TARGET) ${SDK_DIR}/hal/utils/include ${SDK_DIR}/hpl/port ${SDK_DIR}/hri - ${SDK_DIR}/CMSIS/Include + ${CMSIS_5}/CMSIS/Core/Include ) update_board(${BOARD_TARGET}) - if (NOT DEFINED LD_FILE_${CMAKE_C_COMPILER_ID}) - message(FATAL_ERROR "LD_FILE_${CMAKE_C_COMPILER_ID} not defined") - endif () - - if (NOT DEFINED STARTUP_FILE_${CMAKE_C_COMPILER_ID}) - set(STARTUP_FILE_GNU ${SDK_DIR}/gcc/gcc/startup_samd51.c) - endif () - - target_sources(${BOARD_TARGET} PRIVATE - ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} - ) - 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}" + #"LINKER:-lcrt0" + ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" From 4a183d2e3fd0acb54002fa22dc1dc9be5c1a23f4 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 19 Apr 2024 14:05:31 +0700 Subject: [PATCH 324/454] try to add clang for rp2040 but pico-sdk does not support that. (got assert.h file not found) --- hw/bsp/rp2040/family.cmake | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake index 861d20bdd..a298e684b 100644 --- a/hw/bsp/rp2040/family.cmake +++ b/hw/bsp/rp2040/family.cmake @@ -6,6 +6,12 @@ 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() + # add the SDK in case we are standalone tinyusb example (noop if already present) include(${CMAKE_CURRENT_LIST_DIR}/pico_sdk_import.cmake) @@ -30,13 +36,13 @@ endif() add_library(tinyusb_common_base INTERFACE) target_sources(tinyusb_common_base INTERFACE - ${TOP}/src/tusb.c - ${TOP}/src/common/tusb_fifo.c - ) + ${TOP}/src/tusb.c + ${TOP}/src/common/tusb_fifo.c + ) target_include_directories(tinyusb_common_base INTERFACE - ${TOP}/src - ) + ${TOP}/src + ) if(DEFINED LOG) set(TINYUSB_DEBUG_LEVEL ${LOG}) @@ -48,9 +54,9 @@ else () endif() target_compile_definitions(tinyusb_common_base INTERFACE - CFG_TUSB_MCU=OPT_MCU_RP2040 - CFG_TUSB_OS=${TINYUSB_OPT_OS} - CFG_TUSB_DEBUG=${TINYUSB_DEBUG_LEVEL} + CFG_TUSB_MCU=OPT_MCU_RP2040 + CFG_TUSB_OS=${TINYUSB_OPT_OS} + CFG_TUSB_DEBUG=${TINYUSB_DEBUG_LEVEL} ) target_link_libraries(tinyusb_common_base INTERFACE From d157abe77c03c2d058c79585e4700fc1d1d06f9f Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 19 Apr 2024 14:13:48 +0700 Subject: [PATCH 325/454] clang samd21 build but has issue as samd51 --- .../build_system/cmake/cpu/cortex-m0.cmake | 2 +- .../cmake/cpu/cortex-m0plus.cmake | 6 ++++- hw/bsp/samd21/family.cmake | 27 ++++++++++--------- hw/bsp/samd51/family.cmake | 1 - 4 files changed, 21 insertions(+), 15 deletions(-) diff --git a/examples/build_system/cmake/cpu/cortex-m0.cmake b/examples/build_system/cmake/cpu/cortex-m0.cmake index ddf0f16af..62019d90d 100644 --- a/examples/build_system/cmake/cpu/cortex-m0.cmake +++ b/examples/build_system/cmake/cpu/cortex-m0.cmake @@ -9,7 +9,7 @@ if (TOOLCHAIN STREQUAL "gcc") elseif (TOOLCHAIN STREQUAL "clang") set(TOOLCHAIN_COMMON_FLAGS --target=arm-none-eabi - -mcpu=cortex-m0plus + -mcpu=cortex-m0 ) set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") diff --git a/examples/build_system/cmake/cpu/cortex-m0plus.cmake b/examples/build_system/cmake/cpu/cortex-m0plus.cmake index 2438ca96a..ddf0f16af 100644 --- a/examples/build_system/cmake/cpu/cortex-m0plus.cmake +++ b/examples/build_system/cmake/cpu/cortex-m0plus.cmake @@ -7,7 +7,11 @@ if (TOOLCHAIN STREQUAL "gcc") set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "clang") - message(FATAL_ERROR "Clang is not supported for this target") + set(TOOLCHAIN_COMMON_FLAGS + --target=arm-none-eabi + -mcpu=cortex-m0plus + ) + set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "iar") set(TOOLCHAIN_COMMON_FLAGS diff --git a/hw/bsp/samd21/family.cmake b/hw/bsp/samd21/family.cmake index a79a25b54..616c8ae45 100644 --- a/hw/bsp/samd21/family.cmake +++ b/hw/bsp/samd21/family.cmake @@ -18,12 +18,23 @@ set(OPENOCD_OPTION "-f interface/cmsis-dap.cfg -c \"transport select swd\" -f ta # only need to be built ONCE for all examples function(add_board_target BOARD_TARGET) if (NOT TARGET ${BOARD_TARGET}) + 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 () + + if (NOT DEFINED STARTUP_FILE_${CMAKE_C_COMPILER_ID}) + set(STARTUP_FILE_GNU ${SDK_DIR}/gcc/gcc/startup_samd21.c) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + endif () + add_library(${BOARD_TARGET} STATIC ${SDK_DIR}/gcc/system_samd21.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 + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${BOARD_TARGET} PUBLIC ${SDK_DIR} @@ -40,24 +51,16 @@ function(add_board_target BOARD_TARGET) update_board(${BOARD_TARGET}) - if (NOT DEFINED LD_FILE_${CMAKE_C_COMPILER_ID}) - message(FATAL_ERROR "LD_FILE_${CMAKE_C_COMPILER_ID} not defined") - endif () - - if (NOT DEFINED STARTUP_FILE_${CMAKE_C_COMPILER_ID}) - set(STARTUP_FILE_GNU ${SDK_DIR}/gcc/gcc/startup_samd21.c) - endif () - - target_sources(${BOARD_TARGET} PRIVATE - ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} - ) - 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}" diff --git a/hw/bsp/samd51/family.cmake b/hw/bsp/samd51/family.cmake index 08f03f727..8d88cf947 100644 --- a/hw/bsp/samd51/family.cmake +++ b/hw/bsp/samd51/family.cmake @@ -60,7 +60,6 @@ function(add_board_target BOARD_TARGET) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--script=${LD_FILE_Clang}" - #"LINKER:-lcrt0" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${BOARD_TARGET} PUBLIC From 83b4cb178bbcc70949730b5009a9fb85809a8681 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 19 Apr 2024 16:08:49 +0700 Subject: [PATCH 326/454] adding clang for nrf --- hw/bsp/nrf/family.cmake | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/hw/bsp/nrf/family.cmake b/hw/bsp/nrf/family.cmake index 2c4620b97..60dcdf753 100644 --- a/hw/bsp/nrf/family.cmake +++ b/hw/bsp/nrf/family.cmake @@ -30,15 +30,25 @@ set(FAMILY_MCUS NRF5X CACHE INTERNAL "") # only need to be built ONCE for all examples function(add_board_target BOARD_TARGET) if (NOT TARGET ${BOARD_TARGET}) + if (NOT DEFINED LD_FILE_${CMAKE_C_COMPILER_ID}) + set(LD_FILE_GNU ${NRFX_DIR}/mdk/${MCU_VARIANT}_xxaa.ld) + set(LD_FILE_Clang ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/linker/clang/${MCU_VARIANT}_xxaa.ld) + endif () + + if (NOT DEFINED STARTUP_FILE_${CMAKE_C_COMPILER_ID}) + set(STARTUP_FILE_GNU ${NRFX_DIR}/mdk/gcc_startup_${MCU_VARIANT}.S) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + #set(STARTUP_FILE_Clang ${NRFX_DIR}/mdk/arm_startup_${MCU_VARIANT}.s) + endif () + add_library(${BOARD_TARGET} STATIC - # driver ${NRFX_DIR}/helpers/nrfx_flag32_allocator.c ${NRFX_DIR}/drivers/src/nrfx_gpiote.c ${NRFX_DIR}/drivers/src/nrfx_power.c ${NRFX_DIR}/drivers/src/nrfx_spim.c ${NRFX_DIR}/drivers/src/nrfx_uarte.c - # mcu ${NRFX_DIR}/mdk/system_${MCU_VARIANT}.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_compile_definitions(${BOARD_TARGET} PUBLIC CONFIG_GPIO_AS_PINRESET) @@ -67,25 +77,18 @@ function(add_board_target BOARD_TARGET) update_board(${BOARD_TARGET}) - if (NOT DEFINED LD_FILE_${CMAKE_C_COMPILER_ID}) - set(LD_FILE_GNU ${NRFX_DIR}/mdk/${MCU_VARIANT}_xxaa.ld) - endif () - - if (NOT DEFINED STARTUP_FILE_${CMAKE_C_COMPILER_ID}) - set(STARTUP_FILE_GNU ${NRFX_DIR}/mdk/gcc_startup_${MCU_VARIANT}.S) - endif () - - target_sources(${BOARD_TARGET} PUBLIC - ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} - ) - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${BOARD_TARGET} PUBLIC - # linker file "LINKER:--script=${LD_FILE_GNU}" -L${NRFX_DIR}/mdk --specs=nosys.specs --specs=nano.specs ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" + -L${NRFX_DIR}/mdk + -lcrt0 + ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" From 9d1d171b0c54f179b07c4abd3f776da1e512e2fc Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 19 Apr 2024 23:08:27 +0700 Subject: [PATCH 327/454] - update nrfx to v3.4.0 - compile nrf with __STARTUP_CLEAR_BSS and link flag -nostartfiles --- hw/bsp/nrf/boards/pca10056/board.cmake | 1 - hw/bsp/nrf/family.c | 46 +++++++++++++++++++++++--- hw/bsp/nrf/family.cmake | 13 +++++--- hw/bsp/nrf/linker/nrf52840_xxaa.ld | 26 +++++++++++++++ src/portable/nordic/nrf5x/dcd_nrf5x.c | 3 +- tools/get_deps.py | 2 +- 6 files changed, 79 insertions(+), 12 deletions(-) create mode 100644 hw/bsp/nrf/linker/nrf52840_xxaa.ld diff --git a/hw/bsp/nrf/boards/pca10056/board.cmake b/hw/bsp/nrf/boards/pca10056/board.cmake index 693d7beed..cc370aac8 100644 --- a/hw/bsp/nrf/boards/pca10056/board.cmake +++ b/hw/bsp/nrf/boards/pca10056/board.cmake @@ -1,5 +1,4 @@ set(MCU_VARIANT nrf52840) -set(LD_FILE_GNU ${NRFX_DIR}/mdk/nrf52840_xxaa.ld) function(update_board TARGET) endfunction() diff --git a/hw/bsp/nrf/family.c b/hw/bsp/nrf/family.c index 71c651f5f..897d27c59 100644 --- a/hw/bsp/nrf/family.c +++ b/hw/bsp/nrf/family.c @@ -33,6 +33,7 @@ #pragma GCC diagnostic ignored "-Wcast-qual" #pragma GCC diagnostic ignored "-Wcast-align" #pragma GCC diagnostic ignored "-Wunused-parameter" +#pragma GCC diagnostic ignored "-Wunused-variable" #pragma GCC diagnostic ignored "-Wundef" #pragma GCC diagnostic ignored "-Wredundant-decls" #endif @@ -54,6 +55,14 @@ #endif +// There is API changes between nrfx v2 and v3 +#if 85301 >= (10000*MDK_MAJOR_VERSION + 100*MDK_MINOR_VERSION + MDK_MICRO_VERSION) + // note MDK 8.53.1 is also used by nrfx v3.0.0, just skip this version and use later 3.x + #define NRFX_VER 2 +#else + #define NRFX_VER 3 +#endif + //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ @@ -100,11 +109,19 @@ static void max3421_init(void); static nrfx_spim_t _spi = NRFX_SPIM_INSTANCE(1); #endif - //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ +// 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) {} +} + void board_init(void) { // stop LF clock just in case we jump from application without reset NRF_CLOCK->TASKS_LFCLKSTOP = 1UL; @@ -124,6 +141,7 @@ void board_init(void) { SysTick_Config(SystemCoreClock / 1000); // UART + #if NRFX_VER == 2 nrfx_uarte_config_t uart_cfg = { .pseltxd = UART_TX_PIN, .pselrxd = UART_RX_PIN, @@ -137,6 +155,21 @@ void board_init(void) { .parity = NRF_UARTE_PARITY_EXCLUDED, } }; + #elif NRFX_VER == 3 + nrfx_uarte_config_t uart_cfg = { + .txd_pin = UART_TX_PIN, + .rxd_pin = UART_RX_PIN, + .rts_pin = NRF_UARTE_PSEL_DISCONNECTED, + .cts_pin = NRF_UARTE_PSEL_DISCONNECTED, + .p_context = NULL, + .baudrate = NRF_UARTE_BAUDRATE_115200, // CFG_BOARD_UART_BAUDRATE + .interrupt_priority = 7, + .config = { + .hwfc = NRF_UARTE_HWFC_DISABLED, + .parity = NRF_UARTE_PARITY_EXCLUDED, + } + }; + #endif nrfx_uarte_init(&_uart_id, &uart_cfg, NULL); //uart_handler); @@ -224,11 +257,17 @@ int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; return 0; -// return NRFX_SUCCESS == nrfx_uart_rx(&_uart_id, buf, (size_t) len) ? len : 0; +// nrfx_err_t err = nrfx_uarte_rx(&_uart_id, buf, (size_t) len); +// return NRFX_SUCCESS == err ? len : 0; } int board_uart_write(void const* buf, int len) { - return (NRFX_SUCCESS == nrfx_uarte_tx(&_uart_id, (uint8_t const*) buf, (size_t) len)) ? len : 0; + nrfx_err_t err = nrfx_uarte_tx(&_uart_id, (uint8_t const*) buf, (size_t) len + #if NRFX_VER == 3 + ,0 + #endif + ); + return (NRFX_SUCCESS == err) ? len : 0; } #if CFG_TUSB_OS == OPT_OS_NONE @@ -241,7 +280,6 @@ void SysTick_Handler(void) { uint32_t board_millis(void) { return system_ticks; } - #endif #ifdef SOFTDEVICE_PRESENT diff --git a/hw/bsp/nrf/family.cmake b/hw/bsp/nrf/family.cmake index 60dcdf753..c038a2035 100644 --- a/hw/bsp/nrf/family.cmake +++ b/hw/bsp/nrf/family.cmake @@ -31,14 +31,13 @@ set(FAMILY_MCUS NRF5X CACHE INTERNAL "") function(add_board_target BOARD_TARGET) if (NOT TARGET ${BOARD_TARGET}) if (NOT DEFINED LD_FILE_${CMAKE_C_COMPILER_ID}) - set(LD_FILE_GNU ${NRFX_DIR}/mdk/${MCU_VARIANT}_xxaa.ld) - set(LD_FILE_Clang ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/linker/clang/${MCU_VARIANT}_xxaa.ld) + set(LD_FILE_GNU ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/linker/${MCU_VARIANT}_xxaa.ld) + set(LD_FILE_Clang ${LD_FILE_GNU}) endif () if (NOT DEFINED STARTUP_FILE_${CMAKE_C_COMPILER_ID}) set(STARTUP_FILE_GNU ${NRFX_DIR}/mdk/gcc_startup_${MCU_VARIANT}.S) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) - #set(STARTUP_FILE_Clang ${NRFX_DIR}/mdk/arm_startup_${MCU_VARIANT}.s) endif () add_library(${BOARD_TARGET} STATIC @@ -48,9 +47,13 @@ function(add_board_target BOARD_TARGET) ${NRFX_DIR}/drivers/src/nrfx_spim.c ${NRFX_DIR}/drivers/src/nrfx_uarte.c ${NRFX_DIR}/mdk/system_${MCU_VARIANT}.c + ${NRFX_DIR}/soc/nrfx_atomic.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) - target_compile_definitions(${BOARD_TARGET} PUBLIC CONFIG_GPIO_AS_PINRESET) + target_compile_definitions(${BOARD_TARGET} PUBLIC + __STARTUP_CLEAR_BSS + CONFIG_GPIO_AS_PINRESET + ) if (MCU_VARIANT STREQUAL "nrf52840") target_compile_definitions(${BOARD_TARGET} PUBLIC NRF52840_XXAA) @@ -82,12 +85,12 @@ function(add_board_target BOARD_TARGET) "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_Clang}" -L${NRFX_DIR}/mdk - -lcrt0 ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${BOARD_TARGET} PUBLIC diff --git a/hw/bsp/nrf/linker/nrf52840_xxaa.ld b/hw/bsp/nrf/linker/nrf52840_xxaa.ld new file mode 100644 index 000000000..8768fe072 --- /dev/null +++ b/hw/bsp/nrf/linker/nrf52840_xxaa.ld @@ -0,0 +1,26 @@ +/* Linker script to configure memory regions. */ + +SEARCH_DIR(.) + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x100000 + EXTFLASH (rx) : ORIGIN = 0x12000000, LENGTH = 0x8000000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x40000 + CODE_RAM (rwx) : ORIGIN = 0x800000, LENGTH = 0x40000 +} + + +INCLUDE "nrf_common.ld" + +/* nrfx v2 linker does not define __tbss_start/end__ __sbss_start/end__*/ +/*__tbss_start__ = __tbss_start;*/ +/*__tbss_end__ = __tbss_end;*/ +/*__sbss_start__ = __sbss_start;*/ +/*__sbss_end__ = __sbss_end;*/ + +/* picolibc crt0 */ +/*__data_source = __copy_table_start__;*/ +/*__tls_base = __tdata_start;*/ +/*PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) );*/ +/*PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) );*/ diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index 38d37bfc6..d31925806 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -58,7 +58,8 @@ /* Try to detect nrfx version if not configured with CFG_TUD_NRF_NRFX_VERSION * nrfx v1 and v2 are concurrently developed. There is no NRFX_VERSION only MDK VERSION which is as follows: - * - v2.6.0: 8.44.1, v2.5.0: 8.40.2, v2.4.0: 8.37.0, v2.3.0: 8.35.0, v2.2.0: 8.32.1, v2.1.0: 8.30.2, v2.0.0: 8.29.0 + * - v3.0.0: 8.53.1 (conflict with v2.11.0), v3.1.0: 8.55.0 ... + * - v2.11.0: 8.53.1, v2.6.0: 8.44.1, v2.5.0: 8.40.2, v2.4.0: 8.37.0, v2.3.0: 8.35.0, v2.2.0: 8.32.1, v2.1.0: 8.30.2, v2.0.0: 8.29.0 * - v1.9.0: 8.40.3, v1.8.6: 8.35.0 (conflict with v2.3.0), v1.8.5: 8.32.3, v1.8.4: 8.32.1 (conflict with v2.2.0), * v1.8.2: 8.32.1 (conflict with v2.2.0), v1.8.1: 8.27.1 * Therefore the check for v1 would be: diff --git a/tools/get_deps.py b/tools/get_deps.py index 85c8c2126..cfa60002a 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -42,7 +42,7 @@ deps_optional = { '0b79559eb411149d36e073c1635c620e576308d4', 'mm32'], 'hw/mcu/nordic/nrfx': ['https://github.com/NordicSemiconductor/nrfx.git', - '2527e3c8449cfd38aee41598e8af8492f410ed15', + '7c47cc0a56ce44658e6da2458e86cd8783ccc4a2', 'nrf'], 'hw/mcu/nuvoton': ['https://github.com/majbthrd/nuc_driver.git', '2204191ec76283371419fbcec207da02e1bc22fa', From 2e383bf90173aa8fa7b4da8a6cded5527907c465 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 22 Apr 2024 12:12:56 +0700 Subject: [PATCH 328/454] dcd nrf change atoimc_bool to atomic_flag --- hw/bsp/nrf/boards/feather_nrf52840_express/board.cmake | 1 - hw/bsp/nrf/family.cmake | 4 ++-- hw/bsp/nrf/linker/nrf52840_s140_v6.ld | 2 +- hw/bsp/nrf/linker/nrf52840_xxaa.ld | 8 +------- hw/bsp/samd51/family.c | 5 +++++ src/portable/nordic/nrf5x/dcd_nrf5x.c | 5 ++--- 6 files changed, 11 insertions(+), 14 deletions(-) diff --git a/hw/bsp/nrf/boards/feather_nrf52840_express/board.cmake b/hw/bsp/nrf/boards/feather_nrf52840_express/board.cmake index 726438d05..6ff1a7b59 100644 --- a/hw/bsp/nrf/boards/feather_nrf52840_express/board.cmake +++ b/hw/bsp/nrf/boards/feather_nrf52840_express/board.cmake @@ -1,6 +1,5 @@ set(MCU_VARIANT nrf52840) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/nrf52840_s140_v6.ld) -#set(LD_FILE_GNU ${NRFX_DIR}/mdk/nrf52840_xxaa.ld) # enable max3421 host driver for this board set(MAX3421_HOST 1) diff --git a/hw/bsp/nrf/family.cmake b/hw/bsp/nrf/family.cmake index c038a2035..52a6fc196 100644 --- a/hw/bsp/nrf/family.cmake +++ b/hw/bsp/nrf/family.cmake @@ -30,10 +30,10 @@ set(FAMILY_MCUS NRF5X CACHE INTERNAL "") # only need to be built ONCE for all examples function(add_board_target BOARD_TARGET) if (NOT TARGET ${BOARD_TARGET}) - if (NOT DEFINED LD_FILE_${CMAKE_C_COMPILER_ID}) + if (NOT DEFINED LD_FILE_GNU) set(LD_FILE_GNU ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/linker/${MCU_VARIANT}_xxaa.ld) - set(LD_FILE_Clang ${LD_FILE_GNU}) endif () + set(LD_FILE_Clang ${LD_FILE_GNU}) if (NOT DEFINED STARTUP_FILE_${CMAKE_C_COMPILER_ID}) set(STARTUP_FILE_GNU ${NRFX_DIR}/mdk/gcc_startup_${MCU_VARIANT}.S) diff --git a/hw/bsp/nrf/linker/nrf52840_s140_v6.ld b/hw/bsp/nrf/linker/nrf52840_s140_v6.ld index e27fa1c91..7cc94a405 100644 --- a/hw/bsp/nrf/linker/nrf52840_s140_v6.ld +++ b/hw/bsp/nrf/linker/nrf52840_s140_v6.ld @@ -1,7 +1,7 @@ /* Linker script to configure memory regions. */ SEARCH_DIR(.) -GROUP(-lgcc -lc -lnosys) +/*GROUP(-lgcc -lc -lnosys) not compatible with clang*/ MEMORY { diff --git a/hw/bsp/nrf/linker/nrf52840_xxaa.ld b/hw/bsp/nrf/linker/nrf52840_xxaa.ld index 8768fe072..377c248bb 100644 --- a/hw/bsp/nrf/linker/nrf52840_xxaa.ld +++ b/hw/bsp/nrf/linker/nrf52840_xxaa.ld @@ -1,6 +1,7 @@ /* Linker script to configure memory regions. */ SEARCH_DIR(.) +/*GROUP(-lgcc -lc -lnosys) not compatible with clang*/ MEMORY { @@ -10,7 +11,6 @@ MEMORY CODE_RAM (rwx) : ORIGIN = 0x800000, LENGTH = 0x40000 } - INCLUDE "nrf_common.ld" /* nrfx v2 linker does not define __tbss_start/end__ __sbss_start/end__*/ @@ -18,9 +18,3 @@ INCLUDE "nrf_common.ld" /*__tbss_end__ = __tbss_end;*/ /*__sbss_start__ = __sbss_start;*/ /*__sbss_end__ = __sbss_end;*/ - -/* picolibc crt0 */ -/*__data_source = __copy_table_start__;*/ -/*__tls_base = __tdata_start;*/ -/*PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) );*/ -/*PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) );*/ diff --git a/hw/bsp/samd51/family.c b/hw/bsp/samd51/family.c index 170c88191..d56d9f695 100644 --- a/hw/bsp/samd51/family.c +++ b/hw/bsp/samd51/family.c @@ -388,3 +388,8 @@ bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const* tx_buf, uint8_t* rx } #endif + +void HardFault_Handler(void) { + __BKPT(0); + while (1); +} diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index d31925806..56e7f39a0 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -119,7 +119,7 @@ static struct { xfer_td_t xfer[EP_CBI_COUNT + 1][2]; // nRF can only carry one DMA at a time, this is used to guard the access to EasyDMA - atomic_bool dma_running; + atomic_flag dma_running; } _dcd; /*------------------------------------------------------------------*/ @@ -155,7 +155,6 @@ static void edpt_dma_start(volatile uint32_t* reg_startep) { // DMA is complete static void edpt_dma_end(void) { - TU_ASSERT(_dcd.dma_running,); atomic_flag_clear(&_dcd.dma_running); } @@ -618,7 +617,7 @@ void dcd_int_handler(uint8_t rhport) { } if (int_status & USBD_INTEN_USBEVENT_Msk) { - TU_LOG(3, "EVENTCAUSE = 0x%04lX\r\n", NRF_USBD->EVENTCAUSE); + TU_LOG(3, "EVENTCAUSE = 0x%04" PRIX32 "\r\n", NRF_USBD->EVENTCAUSE); enum { EVT_CAUSE_MASK = USBD_EVENTCAUSE_SUSPEND_Msk | USBD_EVENTCAUSE_RESUME_Msk | USBD_EVENTCAUSE_USBWUALLOWED_Msk | From c8e533e61222aa3ccdda291709abd6215e685d95 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 22 Apr 2024 14:54:35 +0700 Subject: [PATCH 329/454] fix build with nrfx v3, though max3421e spi does not seem to work well. --- examples/host/cdc_msc_hid/src/cdc_app.c | 4 +- hw/bsp/nrf/family.c | 52 +++++++++++++++++++++---- hw/bsp/nrf/linker/nrf52840_s140_v6.ld | 10 ++++- hw/bsp/nrf/linker/nrf52840_xxaa.ld | 8 ++-- hw/bsp/nrf/nrfx_config.h | 1 + 5 files changed, 60 insertions(+), 15 deletions(-) diff --git a/examples/host/cdc_msc_hid/src/cdc_app.c b/examples/host/cdc_msc_hid/src/cdc_app.c index e275e7943..4a13f8b27 100644 --- a/examples/host/cdc_msc_hid/src/cdc_app.c +++ b/examples/host/cdc_msc_hid/src/cdc_app.c @@ -72,7 +72,7 @@ void tuh_cdc_rx_cb(uint8_t idx) { uint32_t count = tuh_cdc_read(idx, buf, bufsize); buf[count] = 0; - printf((char*) buf); + printf("%s", (char*) buf); } // Invoked when a device with CDC interface is mounted @@ -89,7 +89,7 @@ void tuh_cdc_mount_cb(uint8_t idx) { // while eneumerating new cdc device cdc_line_coding_t line_coding = {0}; if (tuh_cdc_get_local_line_coding(idx, &line_coding)) { - printf(" Baudrate: %lu, Stop Bits : %u\r\n", line_coding.bit_rate, line_coding.stop_bits); + printf(" Baudrate: %" PRIu32 ", Stop Bits : %u\r\n", line_coding.bit_rate, line_coding.stop_bits); printf(" Parity : %u, Data Width: %u\r\n", line_coding.parity, line_coding.data_bits); } #else diff --git a/hw/bsp/nrf/family.c b/hw/bsp/nrf/family.c index 897d27c59..deae64f05 100644 --- a/hw/bsp/nrf/family.c +++ b/hw/bsp/nrf/family.c @@ -107,6 +107,11 @@ TU_ATTR_UNUSED static void power_event_handler(nrfx_power_usb_evt_t event) { #if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 static void max3421_init(void); static nrfx_spim_t _spi = NRFX_SPIM_INSTANCE(1); + +#if NRFX_VER > 2 +static nrfx_gpiote_t _gpiote = NRFX_GPIOTE_INSTANCE(0); +#endif + #endif //--------------------------------------------------------------------+ @@ -141,7 +146,7 @@ void board_init(void) { SysTick_Config(SystemCoreClock / 1000); // UART - #if NRFX_VER == 2 + #if NRFX_VER <= 2 nrfx_uarte_config_t uart_cfg = { .pseltxd = UART_TX_PIN, .pselrxd = UART_RX_PIN, @@ -155,7 +160,7 @@ void board_init(void) { .parity = NRF_UARTE_PARITY_EXCLUDED, } }; - #elif NRFX_VER == 3 + #else nrfx_uarte_config_t uart_cfg = { .txd_pin = UART_TX_PIN, .rxd_pin = UART_RX_PIN, @@ -263,7 +268,7 @@ int board_uart_read(uint8_t* buf, int len) { int board_uart_write(void const* buf, int len) { nrfx_err_t err = nrfx_uarte_tx(&_uart_id, (uint8_t const*) buf, (size_t) len - #if NRFX_VER == 3 + #if NRFX_VER > 2 ,0 #endif ); @@ -324,8 +329,16 @@ void nrf_error_cb(uint32_t id, uint32_t pc, uint32_t info) { //--------------------------------------------------------------------+ #if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 -void max3421_int_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { - if (!(pin == MAX3421_INTR_PIN && action == NRF_GPIOTE_POLARITY_HITOLO)) return; +#if NRFX_VER <= 2 +void max3421_int_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action ) { + if (action != NRF_GPIOTE_POLARITY_HITOLO) return; +#else +void max3421_int_handler(nrfx_gpiote_pin_t pin, nrfx_gpiote_trigger_t action, void* p_context) { + (void) p_context; + if (action != NRFX_GPIOTE_TRIGGER_HITOLO) return; +#endif + + if (pin != MAX3421_INTR_PIN) return; tuh_int_handler(1, true); } @@ -341,7 +354,11 @@ static void max3421_init(void) { .sck_pin = MAX3421_SCK_PIN, .mosi_pin = MAX3421_MOSI_PIN, .miso_pin = MAX3421_MISO_PIN, + #if NRFX_VER <= 2 .ss_pin = NRFX_SPIM_PIN_NOT_USED, + #else + .ss_pin = NRF_SPIM_PIN_NOT_CONNECTED, + #endif .ss_active_high = false, .irq_priority = 3, .orc = 0xFF, @@ -355,14 +372,35 @@ static void max3421_init(void) { nrfx_spim_init(&_spi, &cfg, NULL, NULL); // max3421e interrupt pin + #if NRFX_VER <= 2 nrfx_gpiote_init(1); nrfx_gpiote_in_config_t in_config = NRFX_GPIOTE_CONFIG_IN_SENSE_HITOLO(true); in_config.pull = NRF_GPIO_PIN_PULLUP; - NVIC_SetPriority(GPIOTE_IRQn, 2); - nrfx_gpiote_in_init(MAX3421_INTR_PIN, &in_config, max3421_int_handler); nrfx_gpiote_trigger_enable(MAX3421_INTR_PIN, true); + #else + nrf_gpio_pin_pull_t intr_pull = NRF_GPIO_PIN_PULLUP; + nrfx_gpiote_trigger_config_t intr_trigger = { + .trigger = NRFX_GPIOTE_TRIGGER_HITOLO, + .p_in_channel = NULL, // sensing mechanism + }; + nrfx_gpiote_handler_config_t intr_handler = { + .handler = max3421_int_handler, + .p_context = NULL, + }; + nrfx_gpiote_input_pin_config_t intr_config = { + .p_pull_config = &intr_pull, + .p_trigger_config = &intr_trigger, + .p_handler_config = &intr_handler, + }; + + nrfx_gpiote_init(&_gpiote, 1); + NVIC_SetPriority(GPIOTE_IRQn, 2); + + nrfx_gpiote_input_configure(&_gpiote, MAX3421_INTR_PIN, &intr_config); + nrfx_gpiote_trigger_enable(&_gpiote, MAX3421_INTR_PIN, true); + #endif } // API to enable/disable MAX3421 INTR pin interrupt diff --git a/hw/bsp/nrf/linker/nrf52840_s140_v6.ld b/hw/bsp/nrf/linker/nrf52840_s140_v6.ld index 7cc94a405..037a14196 100644 --- a/hw/bsp/nrf/linker/nrf52840_s140_v6.ld +++ b/hw/bsp/nrf/linker/nrf52840_s140_v6.ld @@ -5,7 +5,7 @@ SEARCH_DIR(.) MEMORY { - FLASH (rx) : ORIGIN = 0x26000, LENGTH = 0xED000 - 0x26000 + FLASH (rx) : ORIGIN = 0x26000, LENGTH = 0xED000 - 0x26000 /* SRAM required by S132 depend on * - Attribute Table Size @@ -14,7 +14,7 @@ MEMORY * - Concurrent connection peripheral + central + secure links * - Event Len, HVN queue, Write CMD queue */ - RAM (rwx) : ORIGIN = 0x20003400, LENGTH = 0x20040000 - 0x20003400 + RAM (rwx) : ORIGIN = 0x20003400, LENGTH = 0x20040000 - 0x20003400 } SECTIONS @@ -36,3 +36,9 @@ SECTIONS } INSERT AFTER .data; INCLUDE "nrf_common.ld" + +/* nrfx v2 linker does not define __tbss_start/end__ __sbss_start/end__*/ +__tbss_start__ = __tbss_start; +__tbss_end__ = __tbss_end; +__sbss_start__ = __sbss_start; +__sbss_end__ = __sbss_end; diff --git a/hw/bsp/nrf/linker/nrf52840_xxaa.ld b/hw/bsp/nrf/linker/nrf52840_xxaa.ld index 377c248bb..2d20ba7ac 100644 --- a/hw/bsp/nrf/linker/nrf52840_xxaa.ld +++ b/hw/bsp/nrf/linker/nrf52840_xxaa.ld @@ -14,7 +14,7 @@ MEMORY INCLUDE "nrf_common.ld" /* nrfx v2 linker does not define __tbss_start/end__ __sbss_start/end__*/ -/*__tbss_start__ = __tbss_start;*/ -/*__tbss_end__ = __tbss_end;*/ -/*__sbss_start__ = __sbss_start;*/ -/*__sbss_end__ = __sbss_end;*/ +__tbss_start__ = __tbss_start; +__tbss_end__ = __tbss_end; +__sbss_start__ = __sbss_start; +__sbss_end__ = __sbss_end; diff --git a/hw/bsp/nrf/nrfx_config.h b/hw/bsp/nrf/nrfx_config.h index 95ef33ce4..fbec4192b 100644 --- a/hw/bsp/nrf/nrfx_config.h +++ b/hw/bsp/nrf/nrfx_config.h @@ -6,6 +6,7 @@ #define NRFX_CLOCK_ENABLED 0 #define NRFX_GPIOTE_ENABLED 1 +#define NRFX_GPIOTE0_ENABLED 1 #define NRFX_UARTE_ENABLED 1 #define NRFX_UARTE0_ENABLED 1 From 62331f02070bdb1bec2890885008e9f88b06bdb6 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 22 Apr 2024 15:55:50 +0700 Subject: [PATCH 330/454] fix nrfx v3 spim freq when init fix clang build with nrf --- examples/host/cdc_msc_hid/src/msc_app.c | 4 ++-- hw/bsp/nrf/boards/pca10059/pca10059.ld | 8 ++++++- hw/bsp/nrf/boards/pca10095/board.cmake | 1 - hw/bsp/nrf/boards/pca10100/board.cmake | 1 - .../nrf/boards/raytac_mdbt50q_rx/board.cmake | 1 - hw/bsp/nrf/family.c | 6 ++++-- hw/bsp/nrf/family.cmake | 18 ++++++++-------- hw/bsp/nrf/linker/nrf52833_xxaa.ld | 20 ++++++++++++++++++ hw/bsp/nrf/linker/nrf5340_xxaa_application.ld | 21 +++++++++++++++++++ src/class/cdc/cdc_host.c | 4 ++-- src/host/usbh.c | 2 +- 11 files changed, 66 insertions(+), 20 deletions(-) create mode 100644 hw/bsp/nrf/linker/nrf52833_xxaa.ld create mode 100644 hw/bsp/nrf/linker/nrf5340_xxaa_application.ld diff --git a/examples/host/cdc_msc_hid/src/msc_app.c b/examples/host/cdc_msc_hid/src/msc_app.c index e9c9676b8..1d7e18e6e 100644 --- a/examples/host/cdc_msc_hid/src/msc_app.c +++ b/examples/host/cdc_msc_hid/src/msc_app.c @@ -48,8 +48,8 @@ bool inquiry_complete_cb(uint8_t dev_addr, tuh_msc_complete_data_t const * cb_da uint32_t const block_count = tuh_msc_get_block_count(dev_addr, cbw->lun); uint32_t const block_size = tuh_msc_get_block_size(dev_addr, cbw->lun); - printf("Disk Size: %lu MB\r\n", block_count / ((1024*1024)/block_size)); - printf("Block Count = %lu, Block Size: %lu\r\n", block_count, block_size); + printf("Disk Size: %" PRIu32 " MB\r\n", block_count / ((1024*1024)/block_size)); + printf("Block Count = %" PRIu32 ", Block Size: %" PRIu32 "\r\n", block_count, block_size); return true; } diff --git a/hw/bsp/nrf/boards/pca10059/pca10059.ld b/hw/bsp/nrf/boards/pca10059/pca10059.ld index 510bfdd8c..adc80f3c4 100644 --- a/hw/bsp/nrf/boards/pca10059/pca10059.ld +++ b/hw/bsp/nrf/boards/pca10059/pca10059.ld @@ -1,7 +1,7 @@ /* Linker script to configure memory regions. */ SEARCH_DIR(.) -GROUP(-lgcc -lc -lnosys) +/*GROUP(-lgcc -lc -lnosys) not compatible with clang*/ MEMORY { @@ -11,3 +11,9 @@ MEMORY INCLUDE "nrf_common.ld" + +/* nrfx v2 linker does not define __tbss_start/end__ __sbss_start/end__*/ +__tbss_start__ = __tbss_start; +__tbss_end__ = __tbss_end; +__sbss_start__ = __sbss_start; +__sbss_end__ = __sbss_end; diff --git a/hw/bsp/nrf/boards/pca10095/board.cmake b/hw/bsp/nrf/boards/pca10095/board.cmake index ca5399a3a..95dd30969 100644 --- a/hw/bsp/nrf/boards/pca10095/board.cmake +++ b/hw/bsp/nrf/boards/pca10095/board.cmake @@ -1,5 +1,4 @@ set(MCU_VARIANT nrf5340_application) -set(LD_FILE_GNU ${NRFX_DIR}/mdk/nrf5340_xxaa_application.ld) function(update_board TARGET) target_sources(${TARGET} PRIVATE diff --git a/hw/bsp/nrf/boards/pca10100/board.cmake b/hw/bsp/nrf/boards/pca10100/board.cmake index c30026815..a925dae80 100644 --- a/hw/bsp/nrf/boards/pca10100/board.cmake +++ b/hw/bsp/nrf/boards/pca10100/board.cmake @@ -1,5 +1,4 @@ set(MCU_VARIANT nrf52833) -set(LD_FILE_GNU ${NRFX_DIR}/mdk/nrf52833_xxaa.ld) function(update_board TARGET) endfunction() diff --git a/hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.cmake b/hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.cmake index 693d7beed..cc370aac8 100644 --- a/hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.cmake +++ b/hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.cmake @@ -1,5 +1,4 @@ set(MCU_VARIANT nrf52840) -set(LD_FILE_GNU ${NRFX_DIR}/mdk/nrf52840_xxaa.ld) function(update_board TARGET) endfunction() diff --git a/hw/bsp/nrf/family.c b/hw/bsp/nrf/family.c index deae64f05..aff851ddc 100644 --- a/hw/bsp/nrf/family.c +++ b/hw/bsp/nrf/family.c @@ -356,20 +356,22 @@ static void max3421_init(void) { .miso_pin = MAX3421_MISO_PIN, #if NRFX_VER <= 2 .ss_pin = NRFX_SPIM_PIN_NOT_USED, + .frequency = NRF_SPIM_FREQ_4M, #else .ss_pin = NRF_SPIM_PIN_NOT_CONNECTED, + .frequency = 4000000u, #endif .ss_active_high = false, .irq_priority = 3, .orc = 0xFF, // default setting 4 Mhz, Mode 0, MSB first - .frequency = NRF_SPIM_FREQ_4M, .mode = NRF_SPIM_MODE_0, .bit_order = NRF_SPIM_BIT_ORDER_MSB_FIRST, + .miso_pull = NRF_GPIO_PIN_NOPULL, }; // no handler --> blocking - nrfx_spim_init(&_spi, &cfg, NULL, NULL); + TU_ASSERT(NRFX_SUCCESS == nrfx_spim_init(&_spi, &cfg, NULL, NULL), ); // max3421e interrupt pin #if NRFX_VER <= 2 diff --git a/hw/bsp/nrf/family.cmake b/hw/bsp/nrf/family.cmake index 52a6fc196..56ff62bc4 100644 --- a/hw/bsp/nrf/family.cmake +++ b/hw/bsp/nrf/family.cmake @@ -30,8 +30,14 @@ set(FAMILY_MCUS NRF5X CACHE INTERNAL "") # only need to be built ONCE for all examples function(add_board_target BOARD_TARGET) if (NOT TARGET ${BOARD_TARGET}) + if (MCU_VARIANT STREQUAL "nrf5340_application") + set(MCU_VARIANT_XXAA "nrf5340_xxaa_application") + else () + set(MCU_VARIANT_XXAA "${MCU_VARIANT}_xxaa") + endif () + if (NOT DEFINED LD_FILE_GNU) - set(LD_FILE_GNU ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/linker/${MCU_VARIANT}_xxaa.ld) + set(LD_FILE_GNU ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/linker/${MCU_VARIANT_XXAA}.ld) endif () set(LD_FILE_Clang ${LD_FILE_GNU}) @@ -50,19 +56,13 @@ function(add_board_target BOARD_TARGET) ${NRFX_DIR}/soc/nrfx_atomic.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) + string(TOUPPER "${MCU_VARIANT_XXAA}" MCU_VARIANT_XXAA_UPPER) target_compile_definitions(${BOARD_TARGET} PUBLIC __STARTUP_CLEAR_BSS CONFIG_GPIO_AS_PINRESET + ${MCU_VARIANT_XXAA_UPPER} ) - if (MCU_VARIANT STREQUAL "nrf52840") - target_compile_definitions(${BOARD_TARGET} PUBLIC NRF52840_XXAA) - elseif (MCU_VARIANT STREQUAL "nrf52833") - target_compile_definitions(${BOARD_TARGET} PUBLIC NRF52833_XXAA) - elseif (MCU_VARIANT STREQUAL "nrf5340_application") - target_compile_definitions(${BOARD_TARGET} PUBLIC NRF5340_XXAA NRF5340_XXAA_APPLICATION) - endif () - if (TRACE_ETM STREQUAL "1") # ENABLE_TRACE will cause system_nrf5x.c to set up ETM trace target_compile_definitions(${BOARD_TARGET} PUBLIC ENABLE_TRACE) diff --git a/hw/bsp/nrf/linker/nrf52833_xxaa.ld b/hw/bsp/nrf/linker/nrf52833_xxaa.ld new file mode 100644 index 000000000..ae4d0e5b3 --- /dev/null +++ b/hw/bsp/nrf/linker/nrf52833_xxaa.ld @@ -0,0 +1,20 @@ +/* Linker script to configure memory regions. */ + +SEARCH_DIR(.) +/*GROUP(-lgcc -lc -lnosys) not compatible with clang*/ + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x80000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x20000 + CODE_RAM (rwx) : ORIGIN = 0x800000, LENGTH = 0x20000 +} + + +INCLUDE "nrf_common.ld" + +/* nrfx v2 linker does not define __tbss_start/end__ __sbss_start/end__*/ +__tbss_start__ = __tbss_start; +__tbss_end__ = __tbss_end; +__sbss_start__ = __sbss_start; +__sbss_end__ = __sbss_end; diff --git a/hw/bsp/nrf/linker/nrf5340_xxaa_application.ld b/hw/bsp/nrf/linker/nrf5340_xxaa_application.ld new file mode 100644 index 000000000..31762d0b2 --- /dev/null +++ b/hw/bsp/nrf/linker/nrf5340_xxaa_application.ld @@ -0,0 +1,21 @@ +/* Linker script to configure memory regions. */ + +SEARCH_DIR(.) +/*GROUP(-lgcc -lc) not compatible with clang*/ + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x100000 + EXTFLASH (rx) : ORIGIN = 0x10000000, LENGTH = 0x8000000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x40000 + RAM1 (rwx) : ORIGIN = 0x20040000, LENGTH = 0x3F000 +} + + +INCLUDE "nrf_common.ld" + +/* nrfx v2 linker does not define __tbss_start/end__ __sbss_start/end__*/ +__tbss_start__ = __tbss_start; +__tbss_end__ = __tbss_end; +__sbss_start__ = __sbss_start; +__sbss_end__ = __sbss_end; diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 5bdd41f1f..133a10f6e 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -1079,7 +1079,7 @@ static uint32_t ftdi_232bm_baud_to_divisor(uint32_t baud) { static bool ftdi_sio_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { uint16_t const divisor = (uint16_t) ftdi_232bm_baud_to_divisor(baudrate); - TU_LOG_DRV("CDC FTDI Set BaudRate = %lu, divisor = 0x%04x\r\n", baudrate, divisor); + TU_LOG_DRV("CDC FTDI Set BaudRate = %" PRIu32 ", divisor = 0x%04x\r\n", baudrate, divisor); p_cdc->user_control_cb = complete_cb; p_cdc->requested_line_coding.bit_rate = baudrate; @@ -1222,7 +1222,7 @@ static bool cp210x_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t co } static bool cp210x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { - TU_LOG_DRV("CDC CP210x Set BaudRate = %lu\r\n", baudrate); + TU_LOG_DRV("CDC CP210x Set BaudRate = %" PRIu32 "\r\n", baudrate); uint32_t baud_le = tu_htole32(baudrate); p_cdc->user_control_cb = complete_cb; return cp210x_set_request(p_cdc, CP210X_SET_BAUDRATE, 0, (uint8_t *) &baud_le, 4, diff --git a/src/host/usbh.c b/src/host/usbh.c index f8fddf394..7a47f5056 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -704,7 +704,7 @@ static bool usbh_control_xfer_cb (uint8_t daddr, uint8_t ep_addr, xfer_result_t tusb_control_request_t const * request = &_ctrl_xfer.request; if (XFER_RESULT_SUCCESS != result) { - TU_LOG_USBH("[%u:%u] Control %s, xferred_bytes = %lu\r\n", rhport, daddr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED", xferred_bytes); + TU_LOG_USBH("[%u:%u] Control %s, xferred_bytes = %" PRIu32 "\r\n", rhport, daddr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED", xferred_bytes); TU_LOG_BUF_USBH(request, 8); // terminate transfer if any stage failed From c097c85dcf8e0ef3ea052c146c5f514101827251 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 22 Apr 2024 16:17:22 +0700 Subject: [PATCH 331/454] fix print lu format warnings with clang --- examples/device/audio_test_multi_rate/src/main.c | 2 +- examples/device/cdc_uac2/src/uac2_app.c | 4 ++-- examples/device/uac2_headset/src/main.c | 4 ++-- examples/host/bare_api/src/main.c | 2 +- examples/host/cdc_msc_hid_freertos/src/cdc_app.c | 4 ++-- examples/host/cdc_msc_hid_freertos/src/msc_app.c | 4 ++-- examples/host/msc_file_explorer/src/msc_app.c | 6 +++--- src/CMakeLists.txt | 2 +- src/class/cdc/cdc_device.c | 13 ++++++------- src/class/usbtmc/usbtmc_device.c | 2 +- src/portable/nordic/nrf5x/dcd_nrf5x.c | 2 +- tools/get_deps.py | 3 ++- 12 files changed, 24 insertions(+), 24 deletions(-) diff --git a/examples/device/audio_test_multi_rate/src/main.c b/examples/device/audio_test_multi_rate/src/main.c index 3e7f40dac..2ff7f10bd 100644 --- a/examples/device/audio_test_multi_rate/src/main.c +++ b/examples/device/audio_test_multi_rate/src/main.c @@ -272,7 +272,7 @@ bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const * sampFreq = (uint32_t)((audio_control_cur_4_t *)pBuff)->bCur; - TU_LOG2("Clock set current freq: %lu\r\n", sampFreq); + TU_LOG2("Clock set current freq: %" PRIu32 "\r\n", sampFreq); return true; break; diff --git a/examples/device/cdc_uac2/src/uac2_app.c b/examples/device/cdc_uac2/src/uac2_app.c index 98659ea68..c57d98a1a 100644 --- a/examples/device/cdc_uac2/src/uac2_app.c +++ b/examples/device/cdc_uac2/src/uac2_app.c @@ -69,7 +69,7 @@ static bool tud_audio_clock_get_request(uint8_t rhport, audio_control_request_t { if (request->bRequest == AUDIO_CS_REQ_CUR) { - TU_LOG1("Clock get current freq %lu\r\n", current_sample_rate); + TU_LOG1("Clock get current freq %" PRIu32 "\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)); @@ -118,7 +118,7 @@ static bool tud_audio_clock_set_request(uint8_t rhport, audio_control_request_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); + TU_LOG1("Clock set current freq: %" PRIu32 "\r\n", current_sample_rate); return true; } diff --git a/examples/device/uac2_headset/src/main.c b/examples/device/uac2_headset/src/main.c index fbd7ffe22..0ea6e7025 100644 --- a/examples/device/uac2_headset/src/main.c +++ b/examples/device/uac2_headset/src/main.c @@ -157,7 +157,7 @@ static bool tud_audio_clock_get_request(uint8_t rhport, audio_control_request_t { if (request->bRequest == AUDIO_CS_REQ_CUR) { - TU_LOG1("Clock get current freq %lu\r\n", current_sample_rate); + TU_LOG1("Clock get current freq %" PRIu32 "\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)); @@ -206,7 +206,7 @@ static bool tud_audio_clock_set_request(uint8_t rhport, audio_control_request_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); + TU_LOG1("Clock set current freq: %" PRIu32 "\r\n", current_sample_rate); return true; } diff --git a/examples/host/bare_api/src/main.c b/examples/host/bare_api/src/main.c index 14725996d..940840a30 100644 --- a/examples/host/bare_api/src/main.c +++ b/examples/host/bare_api/src/main.c @@ -420,5 +420,5 @@ static void print_utf16(uint16_t *temp_buf, size_t buf_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((char*)temp_buf); + printf("%s", (char*)temp_buf); } 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 6ff513be1..7d246af67 100644 --- a/examples/host/cdc_msc_hid_freertos/src/cdc_app.c +++ b/examples/host/cdc_msc_hid_freertos/src/cdc_app.c @@ -117,7 +117,7 @@ void tuh_cdc_rx_cb(uint8_t idx) { uint32_t count = tuh_cdc_read(idx, buf, bufsize); buf[count] = 0; - printf((char *) buf); + printf("%s", (char *) buf); } void tuh_cdc_mount_cb(uint8_t idx) { @@ -131,7 +131,7 @@ void tuh_cdc_mount_cb(uint8_t idx) { // otherwise you need to call tuh_cdc_set_line_coding() first cdc_line_coding_t line_coding = { 0 }; if (tuh_cdc_get_local_line_coding(idx, &line_coding)) { - printf(" Baudrate: %lu, Stop Bits : %u\r\n", line_coding.bit_rate, line_coding.stop_bits); + printf(" Baudrate: %" PRIu32 ", Stop Bits : %u\r\n", line_coding.bit_rate, line_coding.stop_bits); printf(" Parity : %u, Data Width: %u\r\n", line_coding.parity, line_coding.data_bits); } #endif diff --git a/examples/host/cdc_msc_hid_freertos/src/msc_app.c b/examples/host/cdc_msc_hid_freertos/src/msc_app.c index ee02ba917..9ffd5d965 100644 --- a/examples/host/cdc_msc_hid_freertos/src/msc_app.c +++ b/examples/host/cdc_msc_hid_freertos/src/msc_app.c @@ -47,8 +47,8 @@ bool inquiry_complete_cb(uint8_t dev_addr, tuh_msc_complete_data_t const *cb_dat uint32_t const block_count = tuh_msc_get_block_count(dev_addr, cbw->lun); uint32_t const block_size = tuh_msc_get_block_size(dev_addr, cbw->lun); - printf("Disk Size: %lu MB\r\n", block_count / ((1024 * 1024) / block_size)); - printf("Block Count = %lu, Block Size: %lu\r\n", block_count, block_size); + printf("Disk Size: %" PRIu32 " MB\r\n", block_count / ((1024 * 1024) / block_size)); + printf("Block Count = %" PRIu32 ", Block Size: %" PRIu32 "\r\n", block_count, block_size); return true; } diff --git a/examples/host/msc_file_explorer/src/msc_app.c b/examples/host/msc_file_explorer/src/msc_app.c index ecea614a2..f323e30f0 100644 --- a/examples/host/msc_file_explorer/src/msc_app.c +++ b/examples/host/msc_file_explorer/src/msc_app.c @@ -114,7 +114,7 @@ bool inquiry_complete_cb(uint8_t dev_addr, tuh_msc_complete_data_t const * cb_da uint32_t const block_count = tuh_msc_get_block_count(dev_addr, cbw->lun); uint32_t const block_size = tuh_msc_get_block_size(dev_addr, cbw->lun); - printf("Disk Size: %lu MB\r\n", block_count / ((1024*1024)/block_size)); + printf("Disk Size: %" PRIu32 " MB\r\n", block_count / ((1024*1024)/block_size)); // printf("Block Count = %lu, Block Size: %lu\r\n", block_count, block_size); // For simplicity: we only mount 1 LUN per device @@ -541,10 +541,10 @@ void cli_cmd_ls(EmbeddedCli *cli, char *args, void *context) printf("%-40s", fno.fname); if (fno.fsize < 1024) { - printf("%lu B\r\n", fno.fsize); + printf("%" PRIu32 " B\r\n", fno.fsize); }else { - printf("%lu KB\r\n", fno.fsize / 1024); + printf("%" PRIu32 " KB\r\n", fno.fsize / 1024); } } } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 076e1e1eb..272962332 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -41,7 +41,7 @@ function(add_tinyusb TARGET) ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../lib/networking ) - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") target_compile_options(${TARGET} PRIVATE -Wall -Wextra diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 7ef0530ec..2e0a0c30d 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -43,10 +43,7 @@ //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ -enum -{ - BULK_PACKET_SIZE = (TUD_OPT_HIGH_SPEED ? 512 : 64) -}; +#define BULK_PACKET_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) typedef struct { @@ -176,9 +173,11 @@ uint32_t tud_cdc_n_write(uint8_t itf, void const* buffer, uint32_t bufsize) 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 - // may need to suppress -Wunreachable-code since most of the time CFG_TUD_CDC_TX_BUFSIZE < BULK_PACKET_SIZE - if ( (tu_fifo_count(&p_cdc->tx_ff) >= BULK_PACKET_SIZE) || ((CFG_TUD_CDC_TX_BUFSIZE < BULK_PACKET_SIZE) && tu_fifo_full(&p_cdc->tx_ff)) ) - { + 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); } diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 286cbe108..f6cddfbd7 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -360,7 +360,7 @@ uint16_t usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const * itf_desc, // processing a command (such as a clear). Returns true if it was // in the NAK state and successfully transitioned to the ACK wait // state. -bool tud_usbtmc_start_bus_read() +bool tud_usbtmc_start_bus_read(void) { usbtmcd_state_enum oldState = usbtmc_state.state; switch(oldState) diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index 56e7f39a0..2fe721d6b 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -147,7 +147,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) 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, true); } else { start_dma(reg_startep); } diff --git a/tools/get_deps.py b/tools/get_deps.py index cfa60002a..e08246178 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -177,7 +177,8 @@ deps_optional = { '20285262657d1b482d132d20d755c8c330d55c1f', 'imxrt kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx mm32 msp432e4 nrf ra saml2x' 'stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h5' - 'stm32h7 stm32l0 stm32l1 stm32l4 stm32l5 stm32u5 stm32wb'], + 'stm32h7 stm32l0 stm32l1 stm32l4 stm32l5 stm32u5 stm32wb' + 'sam3x samd11 samd21 samd51 same5x same7x saml2x samg'], 'lib/sct_neopixel': ['https://github.com/gsteiert/sct_neopixel.git', 'e73e04ca63495672d955f9268e003cffe168fcd8', 'lpc55'], From db30eee0fcacda2b2f3f208ddf5ab9be723129d8 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 22 Apr 2024 18:08:41 +0700 Subject: [PATCH 332/454] clang tested with mcb1800, add heap to lpc18 linker --- examples/host/msc_file_explorer/src/main.c | 17 +++------ examples/host/msc_file_explorer/src/msc_app.c | 1 - .../lpc18/boards/lpcxpresso18s37/lpc1837.ld | 34 ++++++++++++----- hw/bsp/lpc18/boards/mcb1800/lpc1857.ld | 37 +++++++++++++------ hw/bsp/lpc18/family.cmake | 8 ++-- hw/bsp/nrf/family.cmake | 3 +- src/portable/ehci/ehci.c | 2 +- 7 files changed, 64 insertions(+), 38 deletions(-) diff --git a/examples/host/msc_file_explorer/src/main.c b/examples/host/msc_file_explorer/src/main.c index 73f3e9eb5..f6b6810f5 100644 --- a/examples/host/msc_file_explorer/src/main.c +++ b/examples/host/msc_file_explorer/src/main.c @@ -72,8 +72,7 @@ extern bool msc_app_init(void); extern void msc_app_task(void); /*------------- MAIN -------------*/ -int main(void) -{ +int main(void) { board_init(); printf("TinyUSB Host MassStorage Explorer Example\r\n"); @@ -87,8 +86,7 @@ int main(void) msc_app_init(); - while (1) - { + while (1) { // tinyusb host task tuh_task(); @@ -103,28 +101,25 @@ int main(void) // TinyUSB Callbacks //--------------------------------------------------------------------+ -void tuh_mount_cb(uint8_t dev_addr) -{ +void tuh_mount_cb(uint8_t dev_addr) { (void) dev_addr; } -void tuh_umount_cb(uint8_t dev_addr) -{ +void tuh_umount_cb(uint8_t dev_addr) { (void) dev_addr; } //--------------------------------------------------------------------+ // Blinking Task //--------------------------------------------------------------------+ -void led_blinking_task(void) -{ +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 + if (board_millis() - start_ms < interval_ms) return; // not enough time start_ms += interval_ms; board_led_write(led_state); diff --git a/examples/host/msc_file_explorer/src/msc_app.c b/examples/host/msc_file_explorer/src/msc_app.c index f323e30f0..ddd39c674 100644 --- a/examples/host/msc_file_explorer/src/msc_app.c +++ b/examples/host/msc_file_explorer/src/msc_app.c @@ -95,7 +95,6 @@ void msc_app_task(void) // //--------------------------------------------------------------------+ - bool inquiry_complete_cb(uint8_t dev_addr, tuh_msc_complete_data_t const * cb_data) { msc_cbw_t const* cbw = cb_data->cbw; diff --git a/hw/bsp/lpc18/boards/lpcxpresso18s37/lpc1837.ld b/hw/bsp/lpc18/boards/lpcxpresso18s37/lpc1837.ld index f1a3add8f..8562a6e71 100644 --- a/hw/bsp/lpc18/boards/lpcxpresso18s37/lpc1837.ld +++ b/hw/bsp/lpc18/boards/lpcxpresso18s37/lpc1837.ld @@ -311,6 +311,20 @@ SECTIONS PROVIDE(end = .); } > RamLoc40 AT> RamLoc40 /* > RamLoc32 AT> RamLoc32 */ + .heap (NOLOAD): { + __heap_start = .; + __HeapBase = .; + __heap_base = .; + __end = .; + PROVIDE(end = .); + PROVIDE(_end = .); + PROVIDE(__end__ = .); + KEEP(*(.heap*)) + __HeapLimit = .; + __heap_limit = .; + __heap_end = .; + } > RamLoc40 + /* NOINIT section for RamLoc40 */ .noinit_RAM2 (NOLOAD) : ALIGN(4) { @@ -383,15 +397,17 @@ SECTIONS PROVIDE(_vStackTop = DEFINED(__user_stack_top) ? __user_stack_top : __top_RamLoc32 - 0); /* ## Create checksum value (used in startup) ## */ - PROVIDE(__valid_user_code_checksum = 0 - - (_vStackTop - + (ResetISR + 1) - + (NMI_Handler + 1) - + (HardFault_Handler + 1) - + (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1) /* MemManage_Handler may not be defined */ - + (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1) /* BusFault_Handler may not be defined */ - + (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1) /* UsageFault_Handler may not be defined */ - ) ); + /* This cause issue with clang linker, so it is disabled */ + /* MemManage_Handler, BusFault_Handler, UsageFault_Handler may not be defined */ +/* PROVIDE(__valid_user_code_checksum = 0 -*/ +/* (_vStackTop*/ +/* + (ResetISR + 1)*/ +/* + (NMI_Handler + 1)*/ +/* + (HardFault_Handler + 1)*/ +/* + (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1)*/ +/* + (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1)*/ +/* + (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1)*/ +/* ) );*/ /* Provide basic symbols giving location and size of main text * block, including initial values of RW data sections. Note that diff --git a/hw/bsp/lpc18/boards/mcb1800/lpc1857.ld b/hw/bsp/lpc18/boards/mcb1800/lpc1857.ld index 837dec364..02ea1088e 100644 --- a/hw/bsp/lpc18/boards/mcb1800/lpc1857.ld +++ b/hw/bsp/lpc18/boards/mcb1800/lpc1857.ld @@ -255,7 +255,6 @@ SECTIONS *(COMMON) . = ALIGN(4) ; _ebss = .; - PROVIDE(end = .); } > RamLoc40 /* RamLoc32 */ /* NOINIT section for RamLoc40 */ @@ -266,6 +265,20 @@ SECTIONS . = ALIGN(4) ; } > RamLoc40 + .heap (NOLOAD): { + __heap_start = .; + __HeapBase = .; + __heap_base = .; + __end = .; + PROVIDE(end = .); + PROVIDE(_end = .); + PROVIDE(__end__ = .); + KEEP(*(.heap*)) + __HeapLimit = .; + __heap_limit = .; + __heap_end = .; + } > RamLoc40 + /* NOINIT section for RamAHB32 */ .noinit_RAM3 (NOLOAD) : ALIGN(4) { @@ -298,19 +311,21 @@ SECTIONS . = ALIGN(4) ; _end_noinit = .; } > RamLoc32 - PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .); + PROVIDE(_vStackTop = DEFINED(__user_stack_top) ? __user_stack_top : __top_RamLoc32 - 0); /* ## Create checksum value (used in startup) ## */ - PROVIDE(__valid_user_code_checksum = 0 - - (_vStackTop - + (ResetISR + 1) - + (NMI_Handler + 1) - + (HardFault_Handler + 1) - + (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1) /* MemManage_Handler may not be defined */ - + (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1) /* BusFault_Handler may not be defined */ - + (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1) /* UsageFault_Handler may not be defined */ - ) ); + /* This cause issue with clang linker, so it is disabled */ + /* MemManage_Handler, BusFault_Handler, UsageFault_Handler may not be defined */ +/* PROVIDE(__valid_user_code_checksum = 0 -*/ +/* (_vStackTop*/ +/* + (ResetISR + 1)*/ +/* + (NMI_Handler + 1)*/ +/* + (HardFault_Handler + 1)*/ +/* + (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1)*/ +/* + (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1)*/ +/* + (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1)*/ +/* ) );*/ /* Provide basic symbols giving location and size of main text * block, including initial values of RW data sections. Note that diff --git a/hw/bsp/lpc18/family.cmake b/hw/bsp/lpc18/family.cmake index 78f4c510b..bf8efabba 100644 --- a/hw/bsp/lpc18/family.cmake +++ b/hw/bsp/lpc18/family.cmake @@ -47,9 +47,11 @@ function(add_board_target BOARD_TARGET) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" - # nanolib - --specs=nosys.specs - --specs=nano.specs + --specs=nosys.specs --specs=nano.specs + ) + 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 diff --git a/hw/bsp/nrf/family.cmake b/hw/bsp/nrf/family.cmake index 56ff62bc4..1d6702720 100644 --- a/hw/bsp/nrf/family.cmake +++ b/hw/bsp/nrf/family.cmake @@ -39,7 +39,6 @@ function(add_board_target BOARD_TARGET) if (NOT DEFINED LD_FILE_GNU) set(LD_FILE_GNU ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/linker/${MCU_VARIANT_XXAA}.ld) endif () - set(LD_FILE_Clang ${LD_FILE_GNU}) if (NOT DEFINED STARTUP_FILE_${CMAKE_C_COMPILER_ID}) set(STARTUP_FILE_GNU ${NRFX_DIR}/mdk/gcc_startup_${MCU_VARIANT}.S) @@ -89,7 +88,7 @@ function(add_board_target BOARD_TARGET) ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--script=${LD_FILE_Clang}" + "LINKER:--script=${LD_FILE_GNU}" -L${NRFX_DIR}/mdk ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c index e145cbb1b..01bbf62bf 100644 --- a/src/portable/ehci/ehci.c +++ b/src/portable/ehci/ehci.c @@ -92,7 +92,7 @@ CFG_TUH_MEM_SECTION TU_ATTR_ALIGNED(4096) static ehci_data_t ehci_data; //--------------------------------------------------------------------+ // Debug //--------------------------------------------------------------------+ -#if CFG_TUSB_DEBUG >= (EHCI_DBG + 1) +#if 0 && CFG_TUSB_DEBUG >= (EHCI_DBG + 1) static inline void print_portsc(ehci_registers_t* regs) { TU_LOG_HEX(EHCI_DBG, regs->portsc); TU_LOG(EHCI_DBG, " Connect Status : %u\r\n", regs->portsc_bm.current_connect_status); From 838a58df99cbdbf08d1535fa9b2d45f8ee5d8b5f Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 22 Apr 2024 19:45:27 +0700 Subject: [PATCH 333/454] clang work with lpc43 --- .../lpc18/boards/lpcxpresso18s37/lpc1837.ld | 5 +- hw/bsp/lpc18/boards/mcb1800/lpc1857.ld | 4 +- hw/bsp/lpc18/family.cmake | 77 ++++++----- hw/bsp/lpc43/boards/ea4357/lpc4357.ld | 39 ++++-- .../lpc43/boards/lpcxpresso43s67/lpc4367.ld | 39 ++++-- hw/bsp/lpc43/family.cmake | 11 +- hw/bsp/nrf/family.cmake | 124 +++++++++--------- tools/get_deps.py | 1 + 8 files changed, 171 insertions(+), 129 deletions(-) diff --git a/hw/bsp/lpc18/boards/lpcxpresso18s37/lpc1837.ld b/hw/bsp/lpc18/boards/lpcxpresso18s37/lpc1837.ld index 8562a6e71..0dd971433 100644 --- a/hw/bsp/lpc18/boards/lpcxpresso18s37/lpc1837.ld +++ b/hw/bsp/lpc18/boards/lpcxpresso18s37/lpc1837.ld @@ -308,9 +308,10 @@ SECTIONS _ebss = .; PROVIDE(__end_bss_RAM = .) ; PROVIDE(__end_bss_RamLoc32 = .) ; - PROVIDE(end = .); +/* PROVIDE(end = .);*/ } > RamLoc40 AT> RamLoc40 /* > RamLoc32 AT> RamLoc32 */ + /* hathach add heap section for clang */ .heap (NOLOAD): { __heap_start = .; __HeapBase = .; @@ -393,7 +394,7 @@ SECTIONS PROVIDE(__end_noinit_RAM = .) ; PROVIDE(__end_noinit_RamLoc32 = .) ; } > RamLoc32 AT> RamLoc32 - PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .); +/* PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .);*/ PROVIDE(_vStackTop = DEFINED(__user_stack_top) ? __user_stack_top : __top_RamLoc32 - 0); /* ## Create checksum value (used in startup) ## */ diff --git a/hw/bsp/lpc18/boards/mcb1800/lpc1857.ld b/hw/bsp/lpc18/boards/mcb1800/lpc1857.ld index 02ea1088e..143aa11ec 100644 --- a/hw/bsp/lpc18/boards/mcb1800/lpc1857.ld +++ b/hw/bsp/lpc18/boards/mcb1800/lpc1857.ld @@ -255,6 +255,7 @@ SECTIONS *(COMMON) . = ALIGN(4) ; _ebss = .; + /* PROVIDE(end = .); */ } > RamLoc40 /* RamLoc32 */ /* NOINIT section for RamLoc40 */ @@ -265,6 +266,7 @@ SECTIONS . = ALIGN(4) ; } > RamLoc40 + /* hathach add heap section for clang */ .heap (NOLOAD): { __heap_start = .; __HeapBase = .; @@ -311,7 +313,7 @@ SECTIONS . = ALIGN(4) ; _end_noinit = .; } > RamLoc32 - +/* PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .);*/ PROVIDE(_vStackTop = DEFINED(__user_stack_top) ? __user_stack_top : __top_RamLoc32 - 0); /* ## Create checksum value (used in startup) ## */ diff --git a/hw/bsp/lpc18/family.cmake b/hw/bsp/lpc18/family.cmake index bf8efabba..309186667 100644 --- a/hw/bsp/lpc18/family.cmake +++ b/hw/bsp/lpc18/family.cmake @@ -1,10 +1,7 @@ include_guard() -if (NOT BOARD) - message(FATAL_ERROR "BOARD not specified") -endif () - set(SDK_DIR ${TOP}/hw/mcu/nxp/lpcopen/lpc18xx/lpc_chip_18xx) +set(CMSIS_5 ${TOP}/lib/CMSIS_5) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) @@ -21,43 +18,44 @@ set(FAMILY_MCUS LPC18XX CACHE INTERNAL "") #------------------------------------ # only need to be built ONCE for all examples function(add_board_target BOARD_TARGET) - if (NOT TARGET ${BOARD_TARGET}) - add_library(${BOARD_TARGET} STATIC - ${SDK_DIR}/../gcc/cr_startup_lpc18xx.c - ${SDK_DIR}/src/chip_18xx_43xx.c - ${SDK_DIR}/src/clock_18xx_43xx.c - ${SDK_DIR}/src/gpio_18xx_43xx.c - ${SDK_DIR}/src/sysinit_18xx_43xx.c - ${SDK_DIR}/src/uart_18xx_43xx.c - ) - target_compile_options(${BOARD_TARGET} PUBLIC - -nostdlib - ) - target_compile_definitions(${BOARD_TARGET} PUBLIC - __USE_LPCOPEN - CORE_M3 - ) - target_include_directories(${BOARD_TARGET} PUBLIC - ${SDK_DIR}/inc - ${SDK_DIR}/inc/config_18xx - ) + if (TARGET ${BOARD_TARGET}) + return() + endif () - update_board(${BOARD_TARGET}) + add_library(${BOARD_TARGET} STATIC + ${SDK_DIR}/../gcc/cr_startup_lpc18xx.c + ${SDK_DIR}/src/chip_18xx_43xx.c + ${SDK_DIR}/src/clock_18xx_43xx.c + ${SDK_DIR}/src/gpio_18xx_43xx.c + ${SDK_DIR}/src/sysinit_18xx_43xx.c + ${SDK_DIR}/src/uart_18xx_43xx.c + ) + target_compile_definitions(${BOARD_TARGET} PUBLIC + __USE_LPCOPEN + CORE_M3 + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${SDK_DIR}/inc + ${SDK_DIR}/inc/config_18xx + ${CMSIS_5}/CMSIS/Core/Include + ) - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--script=${LD_FILE_GNU}" - --specs=nosys.specs --specs=nano.specs - ) - 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 () + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_compile_options(${BOARD_TARGET} PUBLIC -nostdlib) + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + --specs=nosys.specs --specs=nano.specs + ) + 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() @@ -99,5 +97,4 @@ function(family_configure_example TARGET RTOS) # Flashing family_flash_jlink(${TARGET}) - #family_flash_nxplink(${TARGET}) endfunction() diff --git a/hw/bsp/lpc43/boards/ea4357/lpc4357.ld b/hw/bsp/lpc43/boards/ea4357/lpc4357.ld index 53343f6a9..002dcaaed 100644 --- a/hw/bsp/lpc43/boards/ea4357/lpc4357.ld +++ b/hw/bsp/lpc43/boards/ea4357/lpc4357.ld @@ -256,7 +256,7 @@ SECTIONS *(COMMON) . = ALIGN(4) ; _ebss = .; - PROVIDE(end = .); + /* PROVIDE(end = .); */ } > RamLoc40 /* RamLoc32 */ /* NOINIT section for RamLoc40 */ @@ -267,6 +267,21 @@ SECTIONS . = ALIGN(4) ; } > RamLoc40 + /* hathach add heap section for clang */ + .heap (NOLOAD): { + __heap_start = .; + __HeapBase = .; + __heap_base = .; + __end = .; + PROVIDE(end = .); + PROVIDE(_end = .); + PROVIDE(__end__ = .); + KEEP(*(.heap*)) + __HeapLimit = .; + __heap_limit = .; + __heap_end = .; + } > RamLoc40 + /* NOINIT section for RamAHB32 */ .noinit_RAM3 (NOLOAD) : ALIGN(4) { @@ -299,19 +314,21 @@ SECTIONS . = ALIGN(4) ; _end_noinit = .; } > RamLoc32 - PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .); +/* PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .);*/ PROVIDE(_vStackTop = DEFINED(__user_stack_top) ? __user_stack_top : __top_RamLoc32 - 0); /* ## Create checksum value (used in startup) ## */ - PROVIDE(__valid_user_code_checksum = 0 - - (_vStackTop - + (ResetISR + 1) - + (NMI_Handler + 1) - + (HardFault_Handler + 1) - + (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1) /* MemManage_Handler may not be defined */ - + (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1) /* BusFault_Handler may not be defined */ - + (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1) /* UsageFault_Handler may not be defined */ - ) ); + /* This cause issue with clang linker, so it is disabled */ + /* MemManage_Handler, BusFault_Handler, UsageFault_Hander may not be defined */ +/* PROVIDE(__valid_user_code_checksum = 0 -*/ +/* (_vStackTop*/ +/* + (ResetISR + 1)*/ +/* + (NMI_Handler + 1)*/ +/* + (HardFault_Handler + 1)*/ +/* + (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1)*/ +/* + (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1)*/ +/* + (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1)*/ +/* ) );*/ /* Provide basic symbols giving location and size of main text * block, including initial values of RW data sections. Note that diff --git a/hw/bsp/lpc43/boards/lpcxpresso43s67/lpc4367.ld b/hw/bsp/lpc43/boards/lpcxpresso43s67/lpc4367.ld index 99276fb47..f19350e00 100644 --- a/hw/bsp/lpc43/boards/lpcxpresso43s67/lpc4367.ld +++ b/hw/bsp/lpc43/boards/lpcxpresso43s67/lpc4367.ld @@ -304,9 +304,24 @@ SECTIONS _ebss = .; PROVIDE(__end_bss_RAM = .) ; PROVIDE(__end_bss_RamLoc32 = .) ; - PROVIDE(end = .); +/* PROVIDE(end = .);*/ } > RamLoc40 AT> RamLoc40 /* > RamLoc32 AT> RamLoc32 */ + /* hathach add heap section for clang */ + .heap (NOLOAD): { + __heap_start = .; + __HeapBase = .; + __heap_base = .; + __end = .; + PROVIDE(end = .); + PROVIDE(_end = .); + PROVIDE(__end__ = .); + KEEP(*(.heap*)) + __HeapLimit = .; + __heap_limit = .; + __heap_end = .; + } > RamLoc40 + /* NOINIT section for RamLoc40 */ .noinit_RAM2 (NOLOAD) : ALIGN(4) { @@ -376,20 +391,22 @@ SECTIONS PROVIDE(__end_noinit_RamLoc32 = .) ; } > RamLoc32 AT> RamLoc32 - PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .); +/* PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .);*/ PROVIDE(_vStackTop = DEFINED(__user_stack_top) ? __user_stack_top : __top_RamLoc32 - 0); /* ## Create checksum value (used in startup) ## */ - PROVIDE(__valid_user_code_checksum = 0 - - (_vStackTop - + (ResetISR + 1) - + (NMI_Handler + 1) - + (HardFault_Handler + 1) - + (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1) /* MemManage_Handler may not be defined */ - + (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1) /* BusFault_Handler may not be defined */ - + (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1) /* UsageFault_Handler may not be defined */ - ) ); + /* This cause issue with clang linker, so it is disabled */ + /* MemManage_Handler, BusFault_Handler, UsageFault_Hander may not be defined */ +/* PROVIDE(__valid_user_code_checksum = 0 -*/ +/* (_vStackTop*/ +/* + (ResetISR + 1)*/ +/* + (NMI_Handler + 1)*/ +/* + (HardFault_Handler + 1)*/ +/* + (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1)*/ +/* + (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1)*/ +/* + (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1)*/ +/* ) );*/ /* Provide basic symbols giving location and size of main text * block, including initial values of RW data sections. Note that diff --git a/hw/bsp/lpc43/family.cmake b/hw/bsp/lpc43/family.cmake index f66da98aa..2bacd9ea4 100644 --- a/hw/bsp/lpc43/family.cmake +++ b/hw/bsp/lpc43/family.cmake @@ -1,6 +1,7 @@ include_guard() set(SDK_DIR ${TOP}/hw/mcu/nxp/lpcopen/lpc43xx/lpc_chip_43xx) +set(CMSIS_5 ${TOP}/lib/CMSIS_5) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) @@ -23,6 +24,7 @@ function(add_board_target BOARD_TARGET) # Startup & Linker script set(STARTUP_FILE_GNU ${SDK_DIR}/../gcc/cr_startup_lpc43xx.c) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) set(STARTUP_FILE_IAR ${SDK_DIR}/../iar/iar_startup_lpc18xx43xx.s) set(LD_FILE_IAR ${SDK_DIR}/../iar/linker/lpc18xx_43xx_ldscript_iflash.icf) @@ -43,6 +45,7 @@ function(add_board_target BOARD_TARGET) target_include_directories(${BOARD_TARGET} PUBLIC ${SDK_DIR}/inc ${SDK_DIR}/inc/config_43xx + ${CMSIS_5}/CMSIS/Core/Include ) update_board(${BOARD_TARGET}) @@ -51,9 +54,11 @@ function(add_board_target BOARD_TARGET) target_compile_options(${BOARD_TARGET} PUBLIC -nostdlib) target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" - # nanolib - --specs=nosys.specs - --specs=nano.specs + --specs=nosys.specs --specs=nano.specs + ) + 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 diff --git a/hw/bsp/nrf/family.cmake b/hw/bsp/nrf/family.cmake index 1d6702720..b2cd926f9 100644 --- a/hw/bsp/nrf/family.cmake +++ b/hw/bsp/nrf/family.cmake @@ -29,73 +29,75 @@ set(FAMILY_MCUS NRF5X CACHE INTERNAL "") #------------------------------------ # only need to be built ONCE for all examples function(add_board_target BOARD_TARGET) - if (NOT TARGET ${BOARD_TARGET}) - if (MCU_VARIANT STREQUAL "nrf5340_application") - set(MCU_VARIANT_XXAA "nrf5340_xxaa_application") - else () - set(MCU_VARIANT_XXAA "${MCU_VARIANT}_xxaa") - endif () + if (TARGET ${BOARD_TARGET}) + return() + endif () - if (NOT DEFINED LD_FILE_GNU) - set(LD_FILE_GNU ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/linker/${MCU_VARIANT_XXAA}.ld) - endif () + if (MCU_VARIANT STREQUAL "nrf5340_application") + set(MCU_VARIANT_XXAA "nrf5340_xxaa_application") + else () + set(MCU_VARIANT_XXAA "${MCU_VARIANT}_xxaa") + endif () - if (NOT DEFINED STARTUP_FILE_${CMAKE_C_COMPILER_ID}) - set(STARTUP_FILE_GNU ${NRFX_DIR}/mdk/gcc_startup_${MCU_VARIANT}.S) - set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) - endif () + if (NOT DEFINED LD_FILE_GNU) + set(LD_FILE_GNU ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/linker/${MCU_VARIANT_XXAA}.ld) + endif () - add_library(${BOARD_TARGET} STATIC - ${NRFX_DIR}/helpers/nrfx_flag32_allocator.c - ${NRFX_DIR}/drivers/src/nrfx_gpiote.c - ${NRFX_DIR}/drivers/src/nrfx_power.c - ${NRFX_DIR}/drivers/src/nrfx_spim.c - ${NRFX_DIR}/drivers/src/nrfx_uarte.c - ${NRFX_DIR}/mdk/system_${MCU_VARIANT}.c - ${NRFX_DIR}/soc/nrfx_atomic.c - ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + if (NOT DEFINED STARTUP_FILE_${CMAKE_C_COMPILER_ID}) + set(STARTUP_FILE_GNU ${NRFX_DIR}/mdk/gcc_startup_${MCU_VARIANT}.S) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + endif () + + add_library(${BOARD_TARGET} STATIC + ${NRFX_DIR}/helpers/nrfx_flag32_allocator.c + ${NRFX_DIR}/drivers/src/nrfx_gpiote.c + ${NRFX_DIR}/drivers/src/nrfx_power.c + ${NRFX_DIR}/drivers/src/nrfx_spim.c + ${NRFX_DIR}/drivers/src/nrfx_uarte.c + ${NRFX_DIR}/mdk/system_${MCU_VARIANT}.c + ${NRFX_DIR}/soc/nrfx_atomic.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + string(TOUPPER "${MCU_VARIANT_XXAA}" MCU_VARIANT_XXAA_UPPER) + target_compile_definitions(${BOARD_TARGET} PUBLIC + __STARTUP_CLEAR_BSS + CONFIG_GPIO_AS_PINRESET + ${MCU_VARIANT_XXAA_UPPER} + ) + + if (TRACE_ETM STREQUAL "1") + # ENABLE_TRACE will cause system_nrf5x.c to set up ETM trace + target_compile_definitions(${BOARD_TARGET} PUBLIC ENABLE_TRACE) + endif () + + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${NRFX_DIR} + ${NRFX_DIR}/mdk + ${NRFX_DIR}/hal + ${NRFX_DIR}/drivers/include + ${NRFX_DIR}/drivers/src + ${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}" + -L${NRFX_DIR}/mdk + --specs=nosys.specs --specs=nano.specs + -nostartfiles ) - string(TOUPPER "${MCU_VARIANT_XXAA}" MCU_VARIANT_XXAA_UPPER) - target_compile_definitions(${BOARD_TARGET} PUBLIC - __STARTUP_CLEAR_BSS - CONFIG_GPIO_AS_PINRESET - ${MCU_VARIANT_XXAA_UPPER} + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -L${NRFX_DIR}/mdk ) - - if (TRACE_ETM STREQUAL "1") - # ENABLE_TRACE will cause system_nrf5x.c to set up ETM trace - target_compile_definitions(${BOARD_TARGET} PUBLIC ENABLE_TRACE) - endif () - - target_include_directories(${BOARD_TARGET} PUBLIC - ${CMAKE_CURRENT_FUNCTION_LIST_DIR} - ${NRFX_DIR} - ${NRFX_DIR}/mdk - ${NRFX_DIR}/hal - ${NRFX_DIR}/drivers/include - ${NRFX_DIR}/drivers/src - ${CMSIS_DIR}/CMSIS/Core/Include + 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}" - -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 () endif () endfunction() diff --git a/tools/get_deps.py b/tools/get_deps.py index e08246178..ab4783ad7 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -176,6 +176,7 @@ deps_optional = { '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 saml2x' + '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'], From 06c81d8bee7bdf820c4fcaecc06f470061b63b24 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 22 Apr 2024 19:52:55 +0700 Subject: [PATCH 334/454] clang compile with lpc17 --- hw/bsp/lpc17/boards/lpcxpresso1769/lpc1769.ld | 40 +++++++--- hw/bsp/lpc17/boards/mbed1768/lpc1768.ld | 40 +++++++--- hw/bsp/lpc17/family.cmake | 77 ++++++++++--------- hw/bsp/nrf/family.cmake | 4 - 4 files changed, 97 insertions(+), 64 deletions(-) diff --git a/hw/bsp/lpc17/boards/lpcxpresso1769/lpc1769.ld b/hw/bsp/lpc17/boards/lpcxpresso1769/lpc1769.ld index 095bd3d92..ba0543f09 100644 --- a/hw/bsp/lpc17/boards/lpcxpresso1769/lpc1769.ld +++ b/hw/bsp/lpc17/boards/lpcxpresso1769/lpc1769.ld @@ -140,7 +140,7 @@ SECTIONS *(COMMON) . = ALIGN(4) ; _ebss = .; - PROVIDE(end = .); +/* PROVIDE(end = .);*/ } > RamLoc32 /* NOINIT section for RamAHB32 */ @@ -159,19 +159,37 @@ SECTIONS . = ALIGN(4) ; _end_noinit = .; } > RamLoc32 - PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .); + + /* hathach add heap section for clang */ + .heap (NOLOAD): { + __heap_start = .; + __HeapBase = .; + __heap_base = .; + __end = .; + PROVIDE(end = .); + PROVIDE(_end = .); + PROVIDE(__end__ = .); + KEEP(*(.heap*)) + __HeapLimit = .; + __heap_limit = .; + __heap_end = .; + } > RamLoc32 + +/* PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .);*/ PROVIDE(_vStackTop = DEFINED(__user_stack_top) ? __user_stack_top : __top_RamLoc32 - 0); /* ## Create checksum value (used in startup) ## */ - PROVIDE(__valid_user_code_checksum = 0 - - (_vStackTop - + (ResetISR + 1) - + (NMI_Handler + 1) - + (HardFault_Handler + 1) - + (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1) /* MemManage_Handler may not be defined */ - + (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1) /* BusFault_Handler may not be defined */ - + (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1) /* UsageFault_Handler may not be defined */ - ) ); + /* This cause issue with clang linker, so it is disabled */ + /* MemManage_Handler, BusFault_Handler, UsageFault_Handler may not be defined */ +/* PROVIDE(__valid_user_code_checksum = 0 -*/ +/* (_vStackTop*/ +/* + (ResetISR + 1)*/ +/* + (NMI_Handler + 1)*/ +/* + (HardFault_Handler + 1)*/ +/* + (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1)*/ +/* + (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1)*/ +/* + (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1)*/ +/* ) );*/ /* Provide basic symbols giving location and size of main text * block, including initial values of RW data sections. Note that diff --git a/hw/bsp/lpc17/boards/mbed1768/lpc1768.ld b/hw/bsp/lpc17/boards/mbed1768/lpc1768.ld index 095bd3d92..ba0543f09 100644 --- a/hw/bsp/lpc17/boards/mbed1768/lpc1768.ld +++ b/hw/bsp/lpc17/boards/mbed1768/lpc1768.ld @@ -140,7 +140,7 @@ SECTIONS *(COMMON) . = ALIGN(4) ; _ebss = .; - PROVIDE(end = .); +/* PROVIDE(end = .);*/ } > RamLoc32 /* NOINIT section for RamAHB32 */ @@ -159,19 +159,37 @@ SECTIONS . = ALIGN(4) ; _end_noinit = .; } > RamLoc32 - PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .); + + /* hathach add heap section for clang */ + .heap (NOLOAD): { + __heap_start = .; + __HeapBase = .; + __heap_base = .; + __end = .; + PROVIDE(end = .); + PROVIDE(_end = .); + PROVIDE(__end__ = .); + KEEP(*(.heap*)) + __HeapLimit = .; + __heap_limit = .; + __heap_end = .; + } > RamLoc32 + +/* PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .);*/ PROVIDE(_vStackTop = DEFINED(__user_stack_top) ? __user_stack_top : __top_RamLoc32 - 0); /* ## Create checksum value (used in startup) ## */ - PROVIDE(__valid_user_code_checksum = 0 - - (_vStackTop - + (ResetISR + 1) - + (NMI_Handler + 1) - + (HardFault_Handler + 1) - + (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1) /* MemManage_Handler may not be defined */ - + (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1) /* BusFault_Handler may not be defined */ - + (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1) /* UsageFault_Handler may not be defined */ - ) ); + /* This cause issue with clang linker, so it is disabled */ + /* MemManage_Handler, BusFault_Handler, UsageFault_Handler may not be defined */ +/* PROVIDE(__valid_user_code_checksum = 0 -*/ +/* (_vStackTop*/ +/* + (ResetISR + 1)*/ +/* + (NMI_Handler + 1)*/ +/* + (HardFault_Handler + 1)*/ +/* + (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1)*/ +/* + (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1)*/ +/* + (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1)*/ +/* ) );*/ /* Provide basic symbols giving location and size of main text * block, including initial values of RW data sections. Note that diff --git a/hw/bsp/lpc17/family.cmake b/hw/bsp/lpc17/family.cmake index 63ac3149c..cccfdac9f 100644 --- a/hw/bsp/lpc17/family.cmake +++ b/hw/bsp/lpc17/family.cmake @@ -1,10 +1,7 @@ include_guard() -if (NOT BOARD) - message(FATAL_ERROR "BOARD not specified") -endif () - set(SDK_DIR ${TOP}/hw/mcu/nxp/lpcopen/lpc175x_6x/lpc_chip_175x_6x) +set(CMSIS_DIR ${TOP}/lib/CMSIS_5) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) @@ -21,42 +18,46 @@ set(FAMILY_MCUS LPC175X_6X CACHE INTERNAL "") #------------------------------------ # only need to be built ONCE for all examples function(add_board_target BOARD_TARGET) - if (NOT TARGET ${BOARD_TARGET}) - add_library(${BOARD_TARGET} STATIC - ${SDK_DIR}/../gcc/cr_startup_lpc175x_6x.c - ${SDK_DIR}/src/chip_17xx_40xx.c - ${SDK_DIR}/src/clock_17xx_40xx.c - ${SDK_DIR}/src/gpio_17xx_40xx.c - ${SDK_DIR}/src/iocon_17xx_40xx.c - ${SDK_DIR}/src/sysctl_17xx_40xx.c - ${SDK_DIR}/src/sysinit_17xx_40xx.c - ${SDK_DIR}/src/uart_17xx_40xx.c - ) - target_compile_options(${BOARD_TARGET} PUBLIC - -nostdlib - ) - target_compile_definitions(${BOARD_TARGET} PUBLIC - __USE_LPCOPEN - CORE_M3 - RTC_EV_SUPPORT=0 - ) - target_include_directories(${BOARD_TARGET} PUBLIC - ${SDK_DIR}/inc - ) + if (TARGET ${BOARD_TARGET}) + return() + endif () - update_board(${BOARD_TARGET}) + add_library(${BOARD_TARGET} STATIC + ${SDK_DIR}/../gcc/cr_startup_lpc175x_6x.c + ${SDK_DIR}/src/chip_17xx_40xx.c + ${SDK_DIR}/src/clock_17xx_40xx.c + ${SDK_DIR}/src/gpio_17xx_40xx.c + ${SDK_DIR}/src/iocon_17xx_40xx.c + ${SDK_DIR}/src/sysctl_17xx_40xx.c + ${SDK_DIR}/src/sysinit_17xx_40xx.c + ${SDK_DIR}/src/uart_17xx_40xx.c + ) + target_compile_definitions(${BOARD_TARGET} PUBLIC + __USE_LPCOPEN + CORE_M3 + RTC_EV_SUPPORT=0 + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${SDK_DIR}/inc + ${CMSIS_DIR}/CMSIS/Core/Include + ) - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--script=${LD_FILE_GNU}" - # nanolib - --specs=nosys.specs --specs=nano.specs - ) - 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_compile_options(${BOARD_TARGET} PUBLIC -nostdlib) + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + --specs=nosys.specs --specs=nano.specs + ) + 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() diff --git a/hw/bsp/nrf/family.cmake b/hw/bsp/nrf/family.cmake index b2cd926f9..5de69a8a3 100644 --- a/hw/bsp/nrf/family.cmake +++ b/hw/bsp/nrf/family.cmake @@ -1,9 +1,5 @@ include_guard() -if (NOT BOARD) - message(FATAL_ERROR "BOARD not specified") -endif () - set(NRFX_DIR ${TOP}/hw/mcu/nordic/nrfx) set(CMSIS_DIR ${TOP}/lib/CMSIS_5) From fd059ee24dd0e5d7a678b1bd4c0c3b611dd4ee0f Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 22 Apr 2024 20:09:54 +0700 Subject: [PATCH 335/454] clang compile with lpc40 --- hw/bsp/lpc17/boards/lpcxpresso1769/lpc1769.ld | 18 ++++++++--------- hw/bsp/lpc17/boards/mbed1768/lpc1768.ld | 18 ++++++++--------- .../lpc40/boards/ea4088_quickstart/lpc4088.ld | 20 +++++++++++++++++-- hw/bsp/lpc40/family.cmake | 16 ++++++++------- 4 files changed, 45 insertions(+), 27 deletions(-) diff --git a/hw/bsp/lpc17/boards/lpcxpresso1769/lpc1769.ld b/hw/bsp/lpc17/boards/lpcxpresso1769/lpc1769.ld index ba0543f09..a6c35c157 100644 --- a/hw/bsp/lpc17/boards/lpcxpresso1769/lpc1769.ld +++ b/hw/bsp/lpc17/boards/lpcxpresso1769/lpc1769.ld @@ -181,15 +181,15 @@ SECTIONS /* ## Create checksum value (used in startup) ## */ /* This cause issue with clang linker, so it is disabled */ /* MemManage_Handler, BusFault_Handler, UsageFault_Handler may not be defined */ -/* PROVIDE(__valid_user_code_checksum = 0 -*/ -/* (_vStackTop*/ -/* + (ResetISR + 1)*/ -/* + (NMI_Handler + 1)*/ -/* + (HardFault_Handler + 1)*/ -/* + (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1)*/ -/* + (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1)*/ -/* + (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1)*/ -/* ) );*/ + PROVIDE(__valid_user_code_checksum = 0 - + (_vStackTop + + (ResetISR + 1) + + (NMI_Handler + 1) + + (HardFault_Handler + 1) + + (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1) + + (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1) + + (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1) + ) ); /* Provide basic symbols giving location and size of main text * block, including initial values of RW data sections. Note that diff --git a/hw/bsp/lpc17/boards/mbed1768/lpc1768.ld b/hw/bsp/lpc17/boards/mbed1768/lpc1768.ld index ba0543f09..a6c35c157 100644 --- a/hw/bsp/lpc17/boards/mbed1768/lpc1768.ld +++ b/hw/bsp/lpc17/boards/mbed1768/lpc1768.ld @@ -181,15 +181,15 @@ SECTIONS /* ## Create checksum value (used in startup) ## */ /* This cause issue with clang linker, so it is disabled */ /* MemManage_Handler, BusFault_Handler, UsageFault_Handler may not be defined */ -/* PROVIDE(__valid_user_code_checksum = 0 -*/ -/* (_vStackTop*/ -/* + (ResetISR + 1)*/ -/* + (NMI_Handler + 1)*/ -/* + (HardFault_Handler + 1)*/ -/* + (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1)*/ -/* + (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1)*/ -/* + (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1)*/ -/* ) );*/ + PROVIDE(__valid_user_code_checksum = 0 - + (_vStackTop + + (ResetISR + 1) + + (NMI_Handler + 1) + + (HardFault_Handler + 1) + + (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1) + + (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1) + + (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1) + ) ); /* Provide basic symbols giving location and size of main text * block, including initial values of RW data sections. Note that diff --git a/hw/bsp/lpc40/boards/ea4088_quickstart/lpc4088.ld b/hw/bsp/lpc40/boards/ea4088_quickstart/lpc4088.ld index 5897707f6..55b60e1e7 100644 --- a/hw/bsp/lpc40/boards/ea4088_quickstart/lpc4088.ld +++ b/hw/bsp/lpc40/boards/ea4088_quickstart/lpc4088.ld @@ -140,7 +140,7 @@ SECTIONS *(COMMON) . = ALIGN(4) ; _ebss = .; - PROVIDE(end = .); +/* PROVIDE(end = .);*/ } > RamLoc64 /* NOINIT section for RamPeriph32 */ @@ -159,7 +159,23 @@ SECTIONS . = ALIGN(4) ; _end_noinit = .; } > RamLoc64 - PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .); + + /* hathach add heap section for clang */ + .heap (NOLOAD): { + __heap_start = .; + __HeapBase = .; + __heap_base = .; + __end = .; + PROVIDE(end = .); + PROVIDE(_end = .); + PROVIDE(__end__ = .); + KEEP(*(.heap*)) + __HeapLimit = .; + __heap_limit = .; + __heap_end = .; + } > RamLoc64 + +/* PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .);*/ PROVIDE(_vStackTop = DEFINED(__user_stack_top) ? __user_stack_top : __top_RamLoc64 - 0); /* ## Create checksum value (used in startup) ## */ diff --git a/hw/bsp/lpc40/family.cmake b/hw/bsp/lpc40/family.cmake index fce9772b6..4c14da8a7 100644 --- a/hw/bsp/lpc40/family.cmake +++ b/hw/bsp/lpc40/family.cmake @@ -1,6 +1,7 @@ include_guard() set(SDK_DIR ${TOP}/hw/mcu/nxp/lpcopen/lpc40xx/lpc_chip_40xx) +set(CMSIS_DIR ${TOP}/lib/CMSIS_5) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) @@ -9,7 +10,7 @@ include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) 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 LPC18XX CACHE INTERNAL "") +set(FAMILY_MCUS LPC40XX CACHE INTERNAL "") #------------------------------------ @@ -32,9 +33,6 @@ function(add_board_target BOARD_TARGET) ${SDK_DIR}/src/sysinit_17xx_40xx.c ${SDK_DIR}/src/uart_17xx_40xx.c ) - target_compile_options(${BOARD_TARGET} PUBLIC - -nostdlib - ) target_compile_definitions(${BOARD_TARGET} PUBLIC __USE_LPCOPEN CORE_M4 @@ -42,16 +40,20 @@ function(add_board_target BOARD_TARGET) ) target_include_directories(${BOARD_TARGET} PUBLIC ${SDK_DIR}/inc + ${CMSIS_DIR}/CMSIS/Core/Include ) update_board(${BOARD_TARGET}) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_compile_options(${BOARD_TARGET} PUBLIC -nostdlib) + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" - # nanolib - --specs=nosys.specs - --specs=nano.specs ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${BOARD_TARGET} PUBLIC From 6294e4aa43af956d994228707634de8c02512a4c Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 22 Apr 2024 20:39:30 +0700 Subject: [PATCH 336/454] update lpcopen --- 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 ab4783ad7..e9b7b70d8 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -48,7 +48,7 @@ deps_optional = { '2204191ec76283371419fbcec207da02e1bc22fa', 'nuc'], 'hw/mcu/nxp/lpcopen': ['https://github.com/hathach/nxp_lpcopen.git', - '84e0bd3e43910aaf71eefd62075cf57495418312', + '04bfe7a5f6ee74a89a28ad618d3367dcfcfb7d83', 'lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43'], 'hw/mcu/nxp/mcux-sdk': ['https://github.com/hathach/mcux-sdk.git', '144f1eb7ea8c06512e12f12b27383601c0272410', From c9e467822c4f5347515cf8b77023d86b454096fa Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 22 Apr 2024 22:00:45 +0700 Subject: [PATCH 337/454] clang work with imxrt tested with metro rt1011 and rt1060 evk. Don't use startfiles for imxrt --- hw/bsp/imxrt/family.c | 16 ++++++++++++++ hw/bsp/imxrt/family.cmake | 45 ++++++++++++++++++++------------------- 2 files changed, 39 insertions(+), 22 deletions(-) diff --git a/hw/bsp/imxrt/family.c b/hw/bsp/imxrt/family.c index 8ed72aa19..b2e08f9b7 100644 --- a/hw/bsp/imxrt/family.c +++ b/hw/bsp/imxrt/family.c @@ -224,3 +224,19 @@ uint32_t board_millis(void) { return system_ticks; } #endif + + +// 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 diff --git a/hw/bsp/imxrt/family.cmake b/hw/bsp/imxrt/family.cmake index 090014754..f4d7378a5 100644 --- a/hw/bsp/imxrt/family.cmake +++ b/hw/bsp/imxrt/family.cmake @@ -1,9 +1,5 @@ include_guard() -if (NOT BOARD) - message(FATAL_ERROR "BOARD not specified") -endif () - set(SDK_DIR ${TOP}/hw/mcu/nxp/mcux-sdk) set(CMSIS_DIR ${TOP}/lib/CMSIS_5) @@ -26,7 +22,21 @@ function(add_board_target BOARD_TARGET) return() endif () + # LD_FILE and STARTUP_FILE can be defined in board.cmake + if (NOT DEFINED LD_FILE_${CMAKE_C_COMPILER_ID}) + set(LD_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/${MCU_VARIANT}xxxxx${MCU_CORE}_flexspi_nor.ld) + #set(LD_FILE_IAR ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/${MCU_VARIANT}xxxxx_flexspi_nor.ld) + endif () + set(LD_FILE_Clang ${LD_FILE_GNU}) + + if (NOT DEFINED STARTUP_FILE_${CMAKE_C_COMPILER_ID}) + set(STARTUP_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_VARIANT_WITH_CORE}.S) + #set(STARTUP_FILE_IAR ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_VARIANT_WITH_CORE}.S) + endif () + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + add_library(${BOARD_TARGET} STATIC + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}/board/clock_config.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}/board/pin_mux.c ${SDK_DIR}/drivers/common/fsl_common.c @@ -52,6 +62,7 @@ function(add_board_target BOARD_TARGET) __ARMFPV5__=0 XIP_EXTERNAL_FLASH=1 XIP_BOOT_HEADER_ENABLE=1 + __STARTUP_CLEAR_BSS ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} @@ -68,31 +79,21 @@ function(add_board_target BOARD_TARGET) update_board(${BOARD_TARGET}) - # LD_FILE and STARTUP_FILE can be defined in board.cmake - if (NOT DEFINED LD_FILE_${CMAKE_C_COMPILER_ID}) - set(LD_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/${MCU_VARIANT}xxxxx${MCU_CORE}_flexspi_nor.ld) - #set(LD_FILE_IAR ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/${MCU_VARIANT}xxxxx_flexspi_nor.ld) - endif () - - if (NOT DEFINED STARTUP_FILE_${CMAKE_C_COMPILER_ID}) - set(STARTUP_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_VARIANT_WITH_CORE}.S) - #set(STARTUP_FILE_IAR ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_VARIANT_WITH_CORE}.S) - endif () - - target_sources(${BOARD_TARGET} PUBLIC - ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} - ) - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" - # nanolib - --specs=nosys.specs - --specs=nano.specs + -nostartfiles + --specs=nosys.specs --specs=nano.specs # force linker to look for these symbols -Wl,-uimage_vector_table -Wl,-ug_boot_data ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -Wl,-uimage_vector_table + -Wl,-ug_boot_data + ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--config=${LD_FILE_IAR}" From 8da297074809c7e7273d32c35b28ac80cdf56b98 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 22 Apr 2024 22:09:14 +0700 Subject: [PATCH 338/454] clang work with kl25 --- hw/bsp/kinetis_kl/family.c | 16 ++++++++++++++++ hw/bsp/kinetis_kl/family.cmake | 17 +++++++++++------ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/hw/bsp/kinetis_kl/family.c b/hw/bsp/kinetis_kl/family.c index c436be3e6..6078596f0 100644 --- a/hw/bsp/kinetis_kl/family.c +++ b/hw/bsp/kinetis_kl/family.c @@ -141,3 +141,19 @@ uint32_t board_millis(void) return system_ticks; } #endif + + +// 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 diff --git a/hw/bsp/kinetis_kl/family.cmake b/hw/bsp/kinetis_kl/family.cmake index 6d9b65df0..77ac5b599 100644 --- a/hw/bsp/kinetis_kl/family.cmake +++ b/hw/bsp/kinetis_kl/family.cmake @@ -26,7 +26,12 @@ function(add_board_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_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/lpsci/fsl_lpsci.c ${SDK_DIR}/drivers/uart/fsl_uart.c @@ -34,6 +39,7 @@ function(add_board_target BOARD_TARGET) ${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 @@ -48,16 +54,15 @@ function(add_board_target BOARD_TARGET) ) update_board(${BOARD_TARGET}) - # LD_FILE and STARTUP_FILE can be defined in board.cmake - target_sources(${BOARD_TARGET} PUBLIC - ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} - ) - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" - # nanolib --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 From b8f60da8d835843cd44de7187981a2013d5c4d9f Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 22 Apr 2024 22:17:07 +0700 Subject: [PATCH 339/454] clang work with k64f (nostartfiles) --- hw/bsp/kinetis_k/family.c | 17 ++++++- hw/bsp/kinetis_k/family.cmake | 81 ++++++++++++++++++---------------- hw/bsp/kinetis_kl/family.cmake | 1 - 3 files changed, 59 insertions(+), 40 deletions(-) diff --git a/hw/bsp/kinetis_k/family.c b/hw/bsp/kinetis_k/family.c index 6df29c1fc..1c419bc4d 100644 --- a/hw/bsp/kinetis_k/family.c +++ b/hw/bsp/kinetis_k/family.c @@ -140,5 +140,20 @@ void SysTick_Handler(void) { uint32_t board_millis(void) { return system_ticks; } - +#endif + + +// 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 diff --git a/hw/bsp/kinetis_k/family.cmake b/hw/bsp/kinetis_k/family.cmake index 452ef4b26..771754ebd 100644 --- a/hw/bsp/kinetis_k/family.cmake +++ b/hw/bsp/kinetis_k/family.cmake @@ -22,48 +22,53 @@ set(FAMILY_MCUS KINETIS_K CACHE INTERNAL "") #------------------------------------ # only need to be built ONCE for all examples function(add_board_target BOARD_TARGET) - if (NOT TARGET ${BOARD_TARGET}) - add_library(${BOARD_TARGET} STATIC - # driver - ${SDK_DIR}/drivers/gpio/fsl_gpio.c - ${SDK_DIR}/drivers/uart/fsl_uart.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 - ) - 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/port - ${SDK_DIR}/drivers/smc - ${SDK_DIR}/drivers/sysmpu - ${SDK_DIR}/drivers/uart - ) + if (TARGET ${BOARD_TARGET}) + return() + endif () - update_board(${BOARD_TARGET}) + # 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}) - # LD_FILE and STARTUP_FILE can be defined in board.cmake - set(STARTUP_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_VARIANT}.S) + add_library(${BOARD_TARGET} STATIC + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ${SDK_DIR}/drivers/gpio/fsl_gpio.c + ${SDK_DIR}/drivers/uart/fsl_uart.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/port + ${SDK_DIR}/drivers/smc + ${SDK_DIR}/drivers/sysmpu + ${SDK_DIR}/drivers/uart + ) - target_sources(${BOARD_TARGET} PUBLIC - ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + 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}" ) - - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--script=${LD_FILE_GNU}" - # nanolib - --specs=nosys.specs --specs=nano.specs - ) - 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/kinetis_kl/family.cmake b/hw/bsp/kinetis_kl/family.cmake index 77ac5b599..85a913d54 100644 --- a/hw/bsp/kinetis_kl/family.cmake +++ b/hw/bsp/kinetis_kl/family.cmake @@ -108,5 +108,4 @@ function(family_configure_example TARGET RTOS) # Flashing family_flash_jlink(${TARGET}) - #family_flash_nxplink(${TARGET}) endfunction() From 675daf32e929a7c475c2b314769f723ef4d3eb7b Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 22 Apr 2024 22:33:39 +0700 Subject: [PATCH 340/454] skip malloc/free in embedded --- lib/embedded-cli/embedded_cli.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/embedded-cli/embedded_cli.h b/lib/embedded-cli/embedded_cli.h index 33354cd84..91c96f3a1 100644 --- a/lib/embedded-cli/embedded_cli.h +++ b/lib/embedded-cli/embedded_cli.h @@ -743,7 +743,7 @@ EmbeddedCli *embeddedCliNew(EmbeddedCliConfig *config) { bool allocated = false; if (config->cliBuffer == NULL) { - config->cliBuffer = (CLI_UINT *) malloc(totalSize); // malloc guarantees alignment. +// config->cliBuffer = (CLI_UINT *) malloc(totalSize); // malloc guarantees alignment. if (config->cliBuffer == NULL) return NULL; allocated = true; @@ -887,7 +887,7 @@ void embeddedCliFree(EmbeddedCli *cli) { PREPARE_IMPL(cli); if (IS_FLAG_SET(impl->flags, CLI_FLAG_ALLOCATED)) { // allocation is done in single call to malloc, so need only single free - free(cli); +// free(cli); } } From 31a44c0b7e110db990e2a68a077afb8f13207475 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 22 Apr 2024 22:37:37 +0700 Subject: [PATCH 341/454] fix linker libgcc for nrf --- hw/bsp/nrf/boards/arduino_nano33_ble/arduino_nano33_ble.ld | 2 +- hw/bsp/nrf/boards/nrf52840_mdk_dongle/nrf52840_mdk_dongle.ld | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/bsp/nrf/boards/arduino_nano33_ble/arduino_nano33_ble.ld b/hw/bsp/nrf/boards/arduino_nano33_ble/arduino_nano33_ble.ld index b7cac1019..9288a0c5e 100755 --- a/hw/bsp/nrf/boards/arduino_nano33_ble/arduino_nano33_ble.ld +++ b/hw/bsp/nrf/boards/arduino_nano33_ble/arduino_nano33_ble.ld @@ -1,7 +1,7 @@ /* Linker script to configure memory regions. */ SEARCH_DIR(.) -GROUP(-lgcc -lc -lnosys) +/*GROUP(-lgcc -lc -lnosys) not compatible with clang*/ MEMORY { 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 index 78eddc9c3..a6bc6dcfe 100644 --- a/hw/bsp/nrf/boards/nrf52840_mdk_dongle/nrf52840_mdk_dongle.ld +++ b/hw/bsp/nrf/boards/nrf52840_mdk_dongle/nrf52840_mdk_dongle.ld @@ -1,7 +1,7 @@ /* Linker script to configure memory regions. */ SEARCH_DIR(.) -GROUP(-lgcc -lc -lnosys) +/*GROUP(-lgcc -lc -lnosys) not compatible with clang*/ MEMORY { From d486a56ded8b1963308aca1513b7aca5dd8025d7 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 23 Apr 2024 10:03:17 +0700 Subject: [PATCH 342/454] clang work with lpc54 --- hw/bsp/imxrt/family.c | 3 ++ hw/bsp/kinetis_k/family.c | 3 ++ hw/bsp/kinetis_kl/family.c | 3 ++ hw/bsp/lpc54/family.c | 51 +++++++++++++++++----------- hw/bsp/lpc54/family.cmake | 69 ++++++++++++++++++-------------------- hw/bsp/nrf/family.c | 23 ++++++++----- 6 files changed, 88 insertions(+), 64 deletions(-) diff --git a/hw/bsp/imxrt/family.c b/hw/bsp/imxrt/family.c index b2e08f9b7..c9c4918ef 100644 --- a/hw/bsp/imxrt/family.c +++ b/hw/bsp/imxrt/family.c @@ -226,6 +226,7 @@ uint32_t board_millis(void) { #endif +#ifndef __ICCARM__ // Implement _start() since we use linker flag '-nostartfiles'. // Requires defined __STARTUP_CLEAR_BSS, extern int main(void); @@ -240,3 +241,5 @@ void _exit (int __status) { while (1) {} } #endif + +#endif diff --git a/hw/bsp/kinetis_k/family.c b/hw/bsp/kinetis_k/family.c index 1c419bc4d..30dfe6d76 100644 --- a/hw/bsp/kinetis_k/family.c +++ b/hw/bsp/kinetis_k/family.c @@ -143,6 +143,7 @@ uint32_t board_millis(void) { #endif +#ifndef __ICCARM__ // Implement _start() since we use linker flag '-nostartfiles'. // Requires defined __STARTUP_CLEAR_BSS, extern int main(void); @@ -157,3 +158,5 @@ void _exit (int __status) { while (1) {} } #endif + +#endif diff --git a/hw/bsp/kinetis_kl/family.c b/hw/bsp/kinetis_kl/family.c index 6078596f0..254a95176 100644 --- a/hw/bsp/kinetis_kl/family.c +++ b/hw/bsp/kinetis_kl/family.c @@ -143,6 +143,7 @@ uint32_t board_millis(void) #endif +#ifndef __ICCARM__ // Implement _start() since we use linker flag '-nostartfiles'. // Requires defined __STARTUP_CLEAR_BSS, extern int main(void); @@ -157,3 +158,5 @@ void _exit (int __status) { while (1) {} } #endif + +#endif diff --git a/hw/bsp/lpc54/family.c b/hw/bsp/lpc54/family.c index 7411c72d4..5e5732d74 100644 --- a/hw/bsp/lpc54/family.c +++ b/hw/bsp/lpc54/family.c @@ -88,8 +88,7 @@ settings: sources: - {id: SYSCON.fro_hf.outFreq, value: 96 MHz} ******************************************************************/ -void BootClockFROHF96M(void) -{ +void BootClockFROHF96M(void) { /*!< Set up the clock sources */ /*!< Set up FRO */ POWER_DisablePD(kPDRUNCFG_PD_FRO_EN); /*!< Ensure FRO is on */ @@ -110,8 +109,7 @@ void BootClockFROHF96M(void) SystemCoreClock = 96000000U; } -void board_init(void) -{ +void board_init(void) { // Enable IOCON clock CLOCK_EnableClock(kCLOCK_Iocon); @@ -198,38 +196,53 @@ void board_init(void) // Board porting API //--------------------------------------------------------------------+ -void board_led_write(bool state) -{ - GPIO_PinWrite(GPIO, LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +void board_led_write(bool state) { + GPIO_PinWrite(GPIO, LED_PORT, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); } -uint32_t board_button_read(void) -{ +uint32_t board_button_read(void) { // active low return BUTTON_STATE_ACTIVE == GPIO_PinRead(GPIO, 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) -{ - USART_WriteBlocking(UART_DEV, (uint8_t const *) buf, len); +int board_uart_write(void const* buf, int len) { + USART_WriteBlocking(UART_DEV, (uint8_t const*) buf, len); return 0; } #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 + + +#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/lpc54/family.cmake b/hw/bsp/lpc54/family.cmake index 287b437fb..5c61a07f0 100644 --- a/hw/bsp/lpc54/family.cmake +++ b/hw/bsp/lpc54/family.cmake @@ -1,9 +1,5 @@ include_guard() -if (NOT BOARD) - message(FATAL_ERROR "BOARD not specified") -endif () - set(SDK_DIR ${TOP}/hw/mcu/nxp/mcux-sdk) set(CMSIS_DIR ${TOP}/lib/CMSIS_5) @@ -32,7 +28,18 @@ function(add_board_target BOARD_TARGET) return() endif() + if (NOT DEFINED LD_FILE_GNU) + set(LD_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/${MCU_CORE}_flash.ld) + endif () + set(LD_FILE_Clang ${LD_FILE_GNU}) + + if (NOT DEFINED STARTUP_FILE_GNU) + set(STARTUP_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_CORE}.S) + endif () + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + add_library(${BOARD_TARGET} STATIC + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} # driver ${SDK_DIR}/drivers/lpc_gpio/fsl_gpio.c ${SDK_DIR}/drivers/common/fsl_common_arm.c @@ -44,12 +51,27 @@ function(add_board_target BOARD_TARGET) ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_power.c ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_reset.c ) - + target_include_directories(${BOARD_TARGET} PUBLIC + ${TOP}/lib/sct_neopixel + # driver + ${SDK_DIR}/drivers/common + ${SDK_DIR}/drivers/flexcomm + ${SDK_DIR}/drivers/lpc_iocon + ${SDK_DIR}/drivers/lpc_gpio + ${SDK_DIR}/drivers/lpuart + ${SDK_DIR}/drivers/sctimer + # mcu + ${SDK_DIR}/devices/${MCU_VARIANT} + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers + ${CMSIS_DIR}/CMSIS/Core/Include + ) target_compile_definitions(${BOARD_TARGET} PUBLIC CFG_TUSB_MEM_ALIGN=TU_ATTR_ALIGNED\(64\) BOARD_TUD_RHPORT=${PORT} BOARD_TUH_RHPORT=${HOST_PORT} + __STARTUP_CLEAR_BSS ) + # Port 0 is Fullspeed, Port 1 is Highspeed. Port1 controller can only access USB_SRAM if (PORT EQUAL 1) target_compile_definitions(${BOARD_TARGET} PUBLIC @@ -66,42 +88,17 @@ function(add_board_target BOARD_TARGET) ) endif () - target_include_directories(${BOARD_TARGET} PUBLIC - ${TOP}/lib/sct_neopixel - # driver - ${SDK_DIR}/drivers/common - ${SDK_DIR}/drivers/flexcomm - ${SDK_DIR}/drivers/lpc_iocon - ${SDK_DIR}/drivers/lpc_gpio - ${SDK_DIR}/drivers/lpuart - ${SDK_DIR}/drivers/sctimer - # mcu - ${CMSIS_DIR}/CMSIS/Core/Include - ${SDK_DIR}/devices/${MCU_VARIANT} - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers - ) - update_board(${BOARD_TARGET}) - if (NOT DEFINED LD_FILE_${CMAKE_C_COMPILER_ID}) - set(LD_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/${MCU_CORE}_flash.ld) - endif () - - if (NOT DEFINED STARTUP_FILE_${CMAKE_C_COMPILER_ID}) - set(STARTUP_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_CORE}.S) - endif () - - target_sources(${BOARD_TARGET} PUBLIC - ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} - ) - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${BOARD_TARGET} PUBLIC - # linker file "LINKER:--script=${LD_FILE_GNU}" - # nanolib - --specs=nosys.specs - --specs=nano.specs + --specs=nosys.specs --specs=nano.specs + -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 diff --git a/hw/bsp/nrf/family.c b/hw/bsp/nrf/family.c index aff851ddc..885910f9a 100644 --- a/hw/bsp/nrf/family.c +++ b/hw/bsp/nrf/family.c @@ -118,15 +118,6 @@ static nrfx_gpiote_t _gpiote = NRFX_GPIOTE_INSTANCE(0); // //--------------------------------------------------------------------+ -// 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) {} -} - void board_init(void) { // stop LF clock just in case we jump from application without reset NRF_CLOCK->TASKS_LFCLKSTOP = 1UL; @@ -287,6 +278,20 @@ uint32_t board_millis(void) { } #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) {} +} +#endif + +//--------------------------------------------------------------------+ +// Softdevice running +//--------------------------------------------------------------------+ #ifdef SOFTDEVICE_PRESENT // process SOC event from SD uint32_t proc_soc(void) { From 3fd82cfe225cb05c106eccac830bbcf19206bdb1 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 23 Apr 2024 10:57:45 +0700 Subject: [PATCH 343/454] clang work with lpc55 --- examples/device/msc_dual_lun/src/main.c | 25 +++---- hw/bsp/family_support.cmake | 2 +- hw/bsp/lpc55/family.c | 66 +++++++++++-------- hw/bsp/lpc55/family.cmake | 69 ++++++++++---------- src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c | 2 +- 5 files changed, 83 insertions(+), 81 deletions(-) diff --git a/examples/device/msc_dual_lun/src/main.c b/examples/device/msc_dual_lun/src/main.c index de402d3da..aabd0bf8a 100644 --- a/examples/device/msc_dual_lun/src/main.c +++ b/examples/device/msc_dual_lun/src/main.c @@ -39,7 +39,7 @@ * - 1000 ms : device mounted * - 2500 ms : device is suspended */ -enum { +enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, @@ -50,8 +50,7 @@ static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; void led_blinking_task(void); /*------------- MAIN -------------*/ -int main(void) -{ +int main(void) { board_init(); // init device stack on configured roothub port @@ -61,8 +60,7 @@ int main(void) board_init_after_tusb(); } - while (1) - { + while (1) { tud_task(); // tinyusb device task led_blinking_task(); } @@ -73,42 +71,37 @@ 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; } //--------------------------------------------------------------------+ // 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/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index d86ecc0a2..5f0653646 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -239,7 +239,7 @@ function(family_configure_common TARGET RTOS) if (NOT TARGET segger_rtt) add_library(segger_rtt STATIC ${TOP}/lib/SEGGER_RTT/RTT/SEGGER_RTT.c) target_include_directories(segger_rtt PUBLIC ${TOP}/lib/SEGGER_RTT/RTT) - #target_compile_definitions(segger_rtt PUBLIC SEGGER_RTT_MODE_DEFAULT=SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) +# target_compile_definitions(segger_rtt PUBLIC SEGGER_RTT_MODE_DEFAULT=SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) endif() target_link_libraries(${TARGET} PUBLIC segger_rtt) endif () diff --git a/hw/bsp/lpc55/family.c b/hw/bsp/lpc55/family.c index 0fd85988a..cfd5b7032 100644 --- a/hw/bsp/lpc55/family.c +++ b/hw/bsp/lpc55/family.c @@ -72,13 +72,11 @@ //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ -void USB0_IRQHandler(void) -{ +void USB0_IRQHandler(void) { tud_int_handler(0); } -void USB1_IRQHandler(void) -{ +void USB1_IRQHandler(void) { tud_int_handler(1); } @@ -92,8 +90,7 @@ settings: sources: - {id: SYSCON.fro_hf.outFreq, value: 96 MHz} ******************************************************************/ -void BootClockFROHF96M(void) -{ +void BootClockFROHF96M(void) { /*!< Set up the clock sources */ /*!< Set up FRO */ POWER_DisablePD(kPDRUNCFG_PD_FRO192M); /*!< Ensure FRO is on */ @@ -116,8 +113,7 @@ void BootClockFROHF96M(void) SystemCoreClock = 96000000U; } -void board_init(void) -{ +void board_init(void) { // Enable IOCON clock CLOCK_EnableClock(kCLOCK_Iocon); @@ -138,7 +134,7 @@ void board_init(void) // LED IOCON_PinMuxSet(IOCON, LED_PORT, LED_PIN, IOCON_PIO_DIG_FUNC0_EN); - gpio_pin_config_t const led_config = { kGPIO_DigitalOutput, 1}; + gpio_pin_config_t const led_config = {kGPIO_DigitalOutput, 1}; GPIO_PinInit(GPIO, LED_PORT, LED_PIN, &led_config); board_led_write(0); @@ -157,7 +153,7 @@ void board_init(void) // Button IOCON_PinMuxSet(IOCON, BUTTON_PORT, BUTTON_PIN, IOCON_PIO_DIG_FUNC0_EN); - gpio_pin_config_t const button_config = { kGPIO_DigitalInput, 0}; + gpio_pin_config_t const button_config = {kGPIO_DigitalInput, 0}; GPIO_PinInit(GPIO, BUTTON_PORT, BUTTON_PIN, &button_config); #ifdef UART_DEV @@ -170,8 +166,8 @@ void board_init(void) usart_config_t uart_config; USART_GetDefaultConfig(&uart_config); uart_config.baudRate_Bps = CFG_BOARD_UART_BAUDRATE; - uart_config.enableTx = true; - uart_config.enableRx = true; + uart_config.enableTx = true; + uart_config.enableRx = true; USART_Init(UART_DEV, &uart_config, 12000000); #endif @@ -250,9 +246,8 @@ void board_init(void) // Board porting API //--------------------------------------------------------------------+ -void board_led_write(bool state) -{ - GPIO_PinWrite(GPIO, LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +void board_led_write(bool state) { + GPIO_PinWrite(GPIO, LED_PORT, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); #ifdef NEOPIXEL_PIN if (state) { @@ -266,33 +261,50 @@ void board_led_write(bool state) #endif } -uint32_t board_button_read(void) -{ +uint32_t board_button_read(void) { // active low return BUTTON_STATE_ACTIVE == GPIO_PinRead(GPIO, 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) -{ - USART_WriteBlocking(UART_DEV, (uint8_t const *) buf, len); +int board_uart_write(void const* buf, int len) { + USART_WriteBlocking(UART_DEV, (uint8_t const*) buf, len); return 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 + + +#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/lpc55/family.cmake b/hw/bsp/lpc55/family.cmake index 75dabfe5a..21c57fc1f 100644 --- a/hw/bsp/lpc55/family.cmake +++ b/hw/bsp/lpc55/family.cmake @@ -1,9 +1,5 @@ include_guard() -if (NOT BOARD) - message(FATAL_ERROR "BOARD not specified") -endif () - set(SDK_DIR ${TOP}/hw/mcu/nxp/mcux-sdk) set(CMSIS_DIR ${TOP}/lib/CMSIS_5) @@ -30,9 +26,20 @@ set(HOST_PORT $) function(add_board_target BOARD_TARGET) if (TARGET ${BOARD_TARGET}) return() + endif() + + if (NOT DEFINED LD_FILE_GNU) + set(LD_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/${MCU_CORE}_flash.ld) endif () + set(LD_FILE_Clang ${LD_FILE_GNU}) + + if (NOT DEFINED STARTUP_FILE_GNU) + set(STARTUP_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_CORE}.S) + endif () + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) add_library(${BOARD_TARGET} STATIC + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} # driver ${SDK_DIR}/drivers/lpc_gpio/fsl_gpio.c ${SDK_DIR}/drivers/common/fsl_common_arm.c @@ -44,12 +51,27 @@ function(add_board_target BOARD_TARGET) ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_power.c ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_reset.c ) - + target_include_directories(${BOARD_TARGET} PUBLIC + ${TOP}/lib/sct_neopixel + # driver + ${SDK_DIR}/drivers/common + ${SDK_DIR}/drivers/flexcomm + ${SDK_DIR}/drivers/lpc_iocon + ${SDK_DIR}/drivers/lpc_gpio + ${SDK_DIR}/drivers/lpuart + ${SDK_DIR}/drivers/sctimer + # mcu + ${SDK_DIR}/devices/${MCU_VARIANT} + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers + ${CMSIS_DIR}/CMSIS/Core/Include + ) target_compile_definitions(${BOARD_TARGET} PUBLIC CFG_TUSB_MEM_ALIGN=TU_ATTR_ALIGNED\(64\) BOARD_TUD_RHPORT=${PORT} BOARD_TUH_RHPORT=${HOST_PORT} + __STARTUP_CLEAR_BSS ) + # Port 0 is Fullspeed, Port 1 is Highspeed. Port1 controller can only access USB_SRAM if (PORT EQUAL 1) target_compile_definitions(${BOARD_TARGET} PUBLIC @@ -65,42 +87,17 @@ function(add_board_target BOARD_TARGET) ) endif () - target_include_directories(${BOARD_TARGET} PUBLIC - ${TOP}/lib/sct_neopixel - # driver - ${SDK_DIR}/drivers/common - ${SDK_DIR}/drivers/flexcomm - ${SDK_DIR}/drivers/lpc_iocon - ${SDK_DIR}/drivers/lpc_gpio - ${SDK_DIR}/drivers/lpuart - ${SDK_DIR}/drivers/sctimer - # mcu - ${CMSIS_DIR}/CMSIS/Core/Include - ${SDK_DIR}/devices/${MCU_VARIANT} - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers - ) - update_board(${BOARD_TARGET}) - if (NOT DEFINED LD_FILE_${CMAKE_C_COMPILER_ID}) - set(LD_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/${MCU_CORE}_flash.ld) - endif () - - if (NOT DEFINED STARTUP_FILE_${CMAKE_C_COMPILER_ID}) - set(STARTUP_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_CORE}.S) - endif () - - target_sources(${BOARD_TARGET} PUBLIC - ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} - ) - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${BOARD_TARGET} PUBLIC - # linker file "LINKER:--script=${LD_FILE_GNU}" - # nanolib - --specs=nosys.specs - --specs=nano.specs + --specs=nosys.specs --specs=nano.specs + -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 diff --git a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c index f4ed09d83..022904a3a 100644 --- a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c +++ b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c @@ -239,7 +239,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool ep_is_iso(ep_cmd_sts_t* ep_cs, bool is_ return is_highspeed ? (ep_cs[0].cmd_sts.type && !ep_cs[0].cmd_sts.rf_tv) : ep_cs->cmd_sts.type; } -TU_ATTR_ALWAYS_INLINE static inline bool ep_is_bulk(ep_cmd_sts_t* ep_cs) { +TU_ATTR_ALWAYS_INLINE TU_ATTR_UNUSED static inline bool ep_is_bulk(ep_cmd_sts_t* ep_cs) { return (ep_cs[0].cmd_sts.type == 0) && (ep_cs[0].cmd_sts.rf_tv == 0); } From 71e0fd11c8e0da9df7688fdfbfe33d49f4687fbf Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 23 Apr 2024 11:14:11 +0700 Subject: [PATCH 344/454] clang skip mcx since it does not work any more with gcc --- .github/workflows/cmake_arm.yml | 14 +++-- hw/bsp/mcx/family.cmake | 105 ++++++++++++++++---------------- 2 files changed, 61 insertions(+), 58 deletions(-) diff --git a/.github/workflows/cmake_arm.yml b/.github/workflows/cmake_arm.yml index 0c584eb9a..21f4c2324 100644 --- a/.github/workflows/cmake_arm.yml +++ b/.github/workflows/cmake_arm.yml @@ -79,11 +79,13 @@ jobs: ref: develop path: pico-sdk - - name: Build + - name: Get Dependencies run: | sudo apt install -y ninja-build python3 tools/get_deps.py ${{ matrix.family }} - python tools/build_cmake.py ${{ matrix.family }} -DCMAKE_BUILD_TYPE=MinSizeRel + + - name: Build + run: python tools/build_cmake.py ${{ matrix.family }} -DTOOLCHAIN=clang -DCMAKE_BUILD_TYPE=MinSizeRel env: PICO_SDK_PATH: ${{ github.workspace }}/pico-sdk @@ -125,7 +127,7 @@ jobs: - 'kinetis_k kinetis_kl' - 'lpc17 lpc18 lpc40 lpc43' - 'lpc54 lpc55' - - 'mcx' + #- 'mcx' not working with gcc anymore, need to fix this first - 'nrf' - 'ra' - 'rp2040' @@ -178,11 +180,13 @@ jobs: ref: develop path: pico-sdk - - name: Build + - name: Get Dependencies run: | sudo apt install -y ninja-build python3 tools/get_deps.py ${{ matrix.family }} - python tools/build_cmake.py ${{ matrix.family }} -DTOOLCHAIN=clang -DCMAKE_BUILD_TYPE=MinSizeRel + + - name: Build + run: python tools/build_cmake.py ${{ matrix.family }} -DTOOLCHAIN=clang -DCMAKE_BUILD_TYPE=MinSizeRel env: PICO_SDK_PATH: ${{ github.workspace }}/pico-sdk diff --git a/hw/bsp/mcx/family.cmake b/hw/bsp/mcx/family.cmake index c8591b569..223afb9ec 100644 --- a/hw/bsp/mcx/family.cmake +++ b/hw/bsp/mcx/family.cmake @@ -1,9 +1,5 @@ include_guard() -if (NOT BOARD) - message(FATAL_ERROR "BOARD not specified") -endif () - set(SDK_DIR ${TOP}/hw/mcu/nxp/mcux-sdk) set(CMSIS_DIR ${TOP}/lib/CMSIS_5) @@ -28,60 +24,63 @@ set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOL #------------------------------------ # only need to be built ONCE for all examples function(add_board_target BOARD_TARGET) - if (NOT TARGET ${BOARD_TARGET}) - add_library(${BOARD_TARGET} STATIC - # external driver - #lib/sct_neopixel/sct_neopixel.c + if (TARGET ${BOARD_TARGET}) + return() + endif() - # driver - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_gpio.c - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_common_arm.c - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_lpuart.c + if (NOT DEFINED LD_FILE_GNU) + set(LD_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/${MCU_CORE}_flash.ld) + endif () + set(LD_FILE_Clang ${LD_FILE_GNU}) - # mcu - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_reset.c - ${SDK_DIR}/devices/${MCU_VARIANT}/system_${MCU_CORE}.c + if (NOT DEFINED STARTUP_FILE_GNU) + set(STARTUP_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_CORE}.S) + endif() + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + + add_library(${BOARD_TARGET} STATIC + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + # driver + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_gpio.c + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_common_arm.c + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_lpuart.c + # mcu + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_reset.c + ${SDK_DIR}/devices/${MCU_VARIANT}/system_${MCU_CORE}.c + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMSIS_DIR}/CMSIS/Core/Include + ${SDK_DIR}/devices/${MCU_VARIANT} + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers + ) + + if (${FAMILY_MCUS} STREQUAL "MCXN9") + target_sources(${BOARD_TARGET} PRIVATE + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_lpflexcomm.c + ) + elseif(${FAMILY_MCUS} STREQUAL "MCXA15") + target_sources(${BOARD_TARGET} PRIVATE + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_spc.c + ) + endif() + + 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 ) - - if (${FAMILY_MCUS} STREQUAL "MCXN9") - target_sources(${BOARD_TARGET} PRIVATE - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_lpflexcomm.c - ) - elseif(${FAMILY_MCUS} STREQUAL "MCXA15") - target_sources(${BOARD_TARGET} PRIVATE - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_spc.c + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" ) - endif() - - # target_compile_definitions(${BOARD_TARGET} PUBLIC - # ) - target_include_directories(${BOARD_TARGET} PUBLIC - # driver - # mcu - ${CMSIS_DIR}/CMSIS/Core/Include - ${SDK_DIR}/devices/${MCU_VARIANT} - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers + 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_sources(${BOARD_TARGET} PUBLIC - ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_CORE}.S - ) - target_link_options(${BOARD_TARGET} PUBLIC - # linker file - "LINKER:--script=${SDK_DIR}/devices/${MCU_VARIANT}/gcc/${MCU_CORE}_flash.ld" - # nanolib - --specs=nosys.specs - --specs=nano.specs - ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--config=${LD_FILE_IAR}" - ) - endif () endif () endfunction() From 81cdf3ce554674a3c7c71f1f59996a0f3092dc61 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 23 Apr 2024 11:17:20 +0700 Subject: [PATCH 345/454] bump up gcc to 12.3 --- .github/workflows/cmake_arm.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cmake_arm.yml b/.github/workflows/cmake_arm.yml index 21f4c2324..512db64cf 100644 --- a/.github/workflows/cmake_arm.yml +++ b/.github/workflows/cmake_arm.yml @@ -66,7 +66,7 @@ jobs: - name: Install ARM GCC uses: carlosperate/arm-none-eabi-gcc-action@v1 with: - release: '11.2-2022.02' + release: '12.3.Rel1' - name: Checkout TinyUSB uses: actions/checkout@v4 @@ -129,7 +129,7 @@ jobs: - 'lpc54 lpc55' #- 'mcx' not working with gcc anymore, need to fix this first - 'nrf' - - 'ra' + #- 'ra' port later - 'rp2040' - 'samd21' - 'samd51' From a410eb345c3c1f1c1da447204a2b2c4a4dad2af4 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 23 Apr 2024 11:25:01 +0700 Subject: [PATCH 346/454] fix ci typo --- .github/workflows/cmake_arm.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cmake_arm.yml b/.github/workflows/cmake_arm.yml index 512db64cf..bc2a98b59 100644 --- a/.github/workflows/cmake_arm.yml +++ b/.github/workflows/cmake_arm.yml @@ -85,7 +85,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 }} -DCMAKE_BUILD_TYPE=MinSizeRel env: PICO_SDK_PATH: ${{ github.workspace }}/pico-sdk From f76d38c92438284533f02697d34d659583bdd9fd Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 23 Apr 2024 11:35:42 +0700 Subject: [PATCH 347/454] clang work with f0 --- hw/bsp/stm32f0/family.cmake | 20 ++++++++++---------- hw/bsp/stm32h7/family.cmake | 7 ++----- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/hw/bsp/stm32f0/family.cmake b/hw/bsp/stm32f0/family.cmake index 89c93c47a..427c56671 100644 --- a/hw/bsp/stm32f0/family.cmake +++ b/hw/bsp/stm32f0/family.cmake @@ -1,9 +1,5 @@ include_guard() -if (NOT BOARD) - message(FATAL_ERROR "BOARD not specified") -endif () - set(ST_FAMILY f0) set(ST_PREFIX stm32${ST_FAMILY}xx) @@ -29,7 +25,10 @@ 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 @@ -49,8 +48,7 @@ function(add_board_target BOARD_TARGET) ${ST_CMSIS}/Include ${ST_HAL_DRIVER}/Inc ) - target_compile_options(${BOARD_TARGET} PUBLIC - ) + #target_compile_options(${BOARD_TARGET} PUBLIC) target_compile_definitions(${BOARD_TARGET} PUBLIC CFG_EXAMPLE_MSC_READONLY ) @@ -61,9 +59,11 @@ function(add_board_target BOARD_TARGET) target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles - # nanolib - --specs=nosys.specs - --specs=nano.specs + --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 @@ -109,5 +109,5 @@ function(family_configure_example TARGET RTOS) # Flashing family_flash_stlink(${TARGET}) - #family_flash_jlink(${TARGET}) + family_flash_jlink(${TARGET}) endfunction() diff --git a/hw/bsp/stm32h7/family.cmake b/hw/bsp/stm32h7/family.cmake index a4123dda7..e5ae6c69d 100644 --- a/hw/bsp/stm32h7/family.cmake +++ b/hw/bsp/stm32h7/family.cmake @@ -1,9 +1,5 @@ include_guard() -if (NOT BOARD) - message(FATAL_ERROR "BOARD not specified") -endif () - set(ST_FAMILY h7) set(ST_PREFIX stm32${ST_FAMILY}xx) @@ -32,6 +28,7 @@ function(add_board_target BOARD_TARGET) 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() @@ -69,7 +66,7 @@ function(add_board_target BOARD_TARGET) ) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--script=${LD_FILE_GNU}" + "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${BOARD_TARGET} PUBLIC From 0f3d6c61b563f8776d6e9f90a8b459a513f79fc1 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 23 Apr 2024 12:04:08 +0700 Subject: [PATCH 348/454] port clang stm32: f1, f2, f3 --- .github/workflows/build_arm.yml | 1 - .github/workflows/cmake_arm.yml | 4 + hw/bsp/stm32f1/family.cmake | 26 ++-- .../boards/stm32f207nucleo/board.cmake | 10 ++ hw/bsp/stm32f2/boards/stm32f207nucleo/board.h | 57 +++++++++ .../stm32f207nucleo.c => family.c} | 108 ++++------------- hw/bsp/stm32f2/family.cmake | 112 ++++++++++++++++++ .../stm32f3/boards/stm32f303disco/board.cmake | 10 ++ hw/bsp/stm32f3/boards/stm32f303disco/board.h | 61 ++++++++++ .../stm32f303disco.c => family.c} | 112 ++++-------------- hw/bsp/stm32f3/family.cmake | 110 +++++++++++++++++ .../stm32f303disco => }/stm32f3xx_hal_conf.h | 0 src/portable/synopsys/dwc2/dcd_dwc2.c | 8 +- 13 files changed, 430 insertions(+), 189 deletions(-) create mode 100644 hw/bsp/stm32f2/boards/stm32f207nucleo/board.cmake create mode 100644 hw/bsp/stm32f2/boards/stm32f207nucleo/board.h rename hw/bsp/stm32f2/{boards/stm32f207nucleo/stm32f207nucleo.c => family.c} (59%) create mode 100644 hw/bsp/stm32f2/family.cmake create mode 100644 hw/bsp/stm32f3/boards/stm32f303disco/board.cmake create mode 100644 hw/bsp/stm32f3/boards/stm32f303disco/board.h rename hw/bsp/stm32f3/{boards/stm32f303disco/stm32f303disco.c => family.c} (59%) create mode 100644 hw/bsp/stm32f3/family.cmake rename hw/bsp/stm32f3/{boards/stm32f303disco => }/stm32f3xx_hal_conf.h (100%) diff --git a/.github/workflows/build_arm.yml b/.github/workflows/build_arm.yml index 9f3270c91..12e6615ea 100644 --- a/.github/workflows/build_arm.yml +++ b/.github/workflows/build_arm.yml @@ -41,7 +41,6 @@ jobs: - 'lpc51' - 'mm32 msp432e4' - 'samd11 same5x saml2x' - - 'stm32f2 stm32f3' - 'stm32l0 stm32wb' - 'tm4c123 xmc4000' steps: diff --git a/.github/workflows/cmake_arm.yml b/.github/workflows/cmake_arm.yml index bc2a98b59..8eb1e3f74 100644 --- a/.github/workflows/cmake_arm.yml +++ b/.github/workflows/cmake_arm.yml @@ -49,6 +49,8 @@ jobs: - 'samd51' - 'stm32f0' - 'stm32f1' + - 'stm32f2' + - 'stm32f3' - 'stm32f4' - 'stm32f7' - 'stm32g0' @@ -135,6 +137,8 @@ jobs: - 'samd51' - 'stm32f0' - 'stm32f1' + - 'stm32f2' + - 'stm32f3' - 'stm32f4' - 'stm32f7' - 'stm32g0' diff --git a/hw/bsp/stm32f1/family.cmake b/hw/bsp/stm32f1/family.cmake index 6657c85ce..cf7e8e9b1 100644 --- a/hw/bsp/stm32f1/family.cmake +++ b/hw/bsp/stm32f1/family.cmake @@ -1,9 +1,5 @@ include_guard() -if (NOT BOARD) - message(FATAL_ERROR "BOARD not specified") -endif () - set(ST_FAMILY f1) set(ST_PREFIX stm32${ST_FAMILY}xx) @@ -29,8 +25,14 @@ 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 @@ -47,10 +49,8 @@ function(add_board_target BOARD_TARGET) ${ST_CMSIS}/Include ${ST_HAL_DRIVER}/Inc ) - target_compile_options(${BOARD_TARGET} PUBLIC - ) - target_compile_definitions(${BOARD_TARGET} PUBLIC - ) + #target_compile_options(${BOARD_TARGET} PUBLIC) + #target_compile_definitions(${BOARD_TARGET} PUBLIC) update_board(${BOARD_TARGET}) @@ -58,9 +58,11 @@ function(add_board_target BOARD_TARGET) target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles - # nanolib - --specs=nosys.specs - --specs=nano.specs + --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 @@ -106,5 +108,5 @@ function(family_configure_example TARGET RTOS) # Flashing family_flash_stlink(${TARGET}) - #family_flash_jlink(${TARGET}) + family_flash_jlink(${TARGET}) endfunction() diff --git a/hw/bsp/stm32f2/boards/stm32f207nucleo/board.cmake b/hw/bsp/stm32f2/boards/stm32f207nucleo/board.cmake new file mode 100644 index 000000000..8f78e6295 --- /dev/null +++ b/hw/bsp/stm32f2/boards/stm32f207nucleo/board.cmake @@ -0,0 +1,10 @@ +set(MCU_VARIANT stm32f207xx) +set(JLINK_DEVICE stm32f207zg) + +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32F207ZGTx_FLASH.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + STM32F207xx + ) +endfunction() diff --git a/hw/bsp/stm32f2/boards/stm32f207nucleo/board.h b/hw/bsp/stm32f2/boards/stm32f207nucleo/board.h new file mode 100644 index 000000000..3301ede27 --- /dev/null +++ b/hw/bsp/stm32f2/boards/stm32f207nucleo/board.h @@ -0,0 +1,57 @@ +#ifndef BOARD_H +#define BOARD_H + +#define LED_PORT GPIOB +#define LED_PIN GPIO_PIN_14 +#define LED_STATE_ON 1 + +#define BUTTON_PORT GPIOC +#define BUTTON_PIN GPIO_PIN_13 +#define BUTTON_STATE_ACTIVE 1 + + +/** + * @brief System Clock Configuration + * The system Clock is configured as follow : + * System Clock source = PLL (HSE) + * SYSCLK(Hz) = 120000000 + * HCLK(Hz) = 120000000 + * AHB Prescaler = 1 + * APB1 Prescaler = 4 + * APB2 Prescaler = 2 + * HSE Frequency(Hz) = 8000000 + * PLL_M = HSE_VALUE/1000000 + * PLL_N = 240 + * PLL_P = 2 + * PLL_Q = 5 + * VDD(V) = 3.3 + * Flash Latency(WS) = 3 + * @param None + * @retval None + */ +static inline void SystemClock_Config(void) { + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + + /* Enable HSE Oscillator and activate PLL with HSE as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = HSE_VALUE / 1000000; + RCC_OscInitStruct.PLL.PLLN = 240; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; + RCC_OscInitStruct.PLL.PLLQ = 5; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 + clocks dividers */ + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3); +} + +#endif diff --git a/hw/bsp/stm32f2/boards/stm32f207nucleo/stm32f207nucleo.c b/hw/bsp/stm32f2/family.c similarity index 59% rename from hw/bsp/stm32f2/boards/stm32f207nucleo/stm32f207nucleo.c rename to hw/bsp/stm32f2/family.c index dfbe7b743..8b1c56423 100644 --- a/hw/bsp/stm32f2/boards/stm32f207nucleo/stm32f207nucleo.c +++ b/hw/bsp/stm32f2/family.c @@ -24,15 +24,14 @@ * This file is part of the TinyUSB stack. */ -#include "bsp/board_api.h" - #include "stm32f2xx_hal.h" +#include "bsp/board_api.h" +#include "board.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ -void OTG_FS_IRQHandler(void) -{ +void OTG_FS_IRQHandler(void) { tud_int_handler(0); } @@ -40,81 +39,24 @@ void OTG_FS_IRQHandler(void) // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ -#define LED_PORT GPIOB -#define LED_PIN GPIO_PIN_14 -#define LED_STATE_ON 1 - -#define BUTTON_PORT GPIOC -#define BUTTON_PIN GPIO_PIN_13 -#define BUTTON_STATE_ACTIVE 1 - - // enable all LED, Button, Uart, USB clock -static void all_rcc_clk_enable(void) -{ +static void all_rcc_clk_enable(void) { __HAL_RCC_GPIOA_CLK_ENABLE(); // USB D+, D- __HAL_RCC_GPIOB_CLK_ENABLE(); // LED __HAL_RCC_GPIOC_CLK_ENABLE(); // Button } -/** - * @brief System Clock Configuration - * The system Clock is configured as follow : - * System Clock source = PLL (HSE) - * SYSCLK(Hz) = 120000000 - * HCLK(Hz) = 120000000 - * AHB Prescaler = 1 - * APB1 Prescaler = 4 - * APB2 Prescaler = 2 - * HSE Frequency(Hz) = 8000000 - * PLL_M = HSE_VALUE/1000000 - * PLL_N = 240 - * PLL_P = 2 - * PLL_Q = 5 - * VDD(V) = 3.3 - * Flash Latency(WS) = 3 - * @param None - * @retval None - */ -void SystemClock_Config(void) -{ - RCC_ClkInitTypeDef RCC_ClkInitStruct; - RCC_OscInitTypeDef RCC_OscInitStruct; - - /* Enable HSE Oscillator and activate PLL with HSE as source */ - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; - RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; - RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; - RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000; - RCC_OscInitStruct.PLL.PLLN = 240; - RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; - RCC_OscInitStruct.PLL.PLLQ = 5; - HAL_RCC_OscConfig(&RCC_OscInitStruct); - - /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 - clocks dividers */ - RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); - RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; - RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; - RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; - RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; - HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3); -} - -void board_init(void) -{ +void board_init(void) { SystemClock_Config(); - #if CFG_TUSB_OS == OPT_OS_NONE + #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); #endif - all_rcc_clk_enable(); - GPIO_InitTypeDef GPIO_InitStruct; + GPIO_InitTypeDef GPIO_InitStruct; // LED GPIO_InitStruct.Pin = LED_PIN; @@ -165,50 +107,44 @@ 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) -{ - (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) { 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 #0\n"); } // 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/stm32f2/family.cmake b/hw/bsp/stm32f2/family.cmake new file mode 100644 index 000000000..862680bce --- /dev/null +++ b/hw/bsp/stm32f2/family.cmake @@ -0,0 +1,112 @@ +include_guard() + +set(ST_FAMILY f2) +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-m3 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS STM32F2 CACHE INTERNAL "") + + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# 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}} + ) + 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 () + 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_STM32F2 ${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_stlink(${TARGET}) + family_flash_jlink(${TARGET}) +endfunction() diff --git a/hw/bsp/stm32f3/boards/stm32f303disco/board.cmake b/hw/bsp/stm32f3/boards/stm32f303disco/board.cmake new file mode 100644 index 000000000..7e02a7910 --- /dev/null +++ b/hw/bsp/stm32f3/boards/stm32f303disco/board.cmake @@ -0,0 +1,10 @@ +set(MCU_VARIANT stm32f303xc) +set(JLINK_DEVICE stm32f303vc) + +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32F303VCTx_FLASH.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + STM32F303xC + ) +endfunction() diff --git a/hw/bsp/stm32f3/boards/stm32f303disco/board.h b/hw/bsp/stm32f3/boards/stm32f303disco/board.h new file mode 100644 index 000000000..706149b49 --- /dev/null +++ b/hw/bsp/stm32f3/boards/stm32f303disco/board.h @@ -0,0 +1,61 @@ +#ifndef BOARD_H +#define BOARD_H + +#define LED_PORT GPIOE +#define LED_PIN GPIO_PIN_9 +#define LED_STATE_ON 1 + +#define BUTTON_PORT GPIOA +#define BUTTON_PIN GPIO_PIN_0 +#define BUTTON_STATE_ACTIVE 1 + + +/** + * @brief System Clock Configuration + * The system Clock is configured as follow : + * System Clock source = PLL (HSE) + * SYSCLK(Hz) = 72000000 + * HCLK(Hz) = 72000000 + * AHB Prescaler = 1 + * APB1 Prescaler = 2 + * APB2 Prescaler = 1 + * HSE Frequency(Hz) = 8000000 + * HSE PREDIV = 1 + * PLLMUL = RCC_PLL_MUL9 (9) + * Flash Latency(WS) = 2 + * @param None + * @retval None + */ +static inline void SystemClock_Config(void) { + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit; + + /* Enable HSE Oscillator and activate PLL with HSE as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /* Configures the USB clock */ + HAL_RCCEx_GetPeriphCLKConfig(&RCC_PeriphClkInit); + RCC_PeriphClkInit.USBClockSelection = RCC_USBCLKSOURCE_PLL_DIV1_5; + HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit); + + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 + clocks dividers */ + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2); + + /* Enable Power Clock */ + __HAL_RCC_PWR_CLK_ENABLE(); +} + +#endif diff --git a/hw/bsp/stm32f3/boards/stm32f303disco/stm32f303disco.c b/hw/bsp/stm32f3/family.c similarity index 59% rename from hw/bsp/stm32f3/boards/stm32f303disco/stm32f303disco.c rename to hw/bsp/stm32f3/family.c index d6a39a8e2..7c194a694 100644 --- a/hw/bsp/stm32f3/boards/stm32f303disco/stm32f303disco.c +++ b/hw/bsp/stm32f3/family.c @@ -24,8 +24,9 @@ * This file is part of the TinyUSB stack. */ -#include "bsp/board_api.h" #include "stm32f3xx_hal.h" +#include "bsp/board_api.h" +#include "board.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler @@ -38,23 +39,20 @@ // USB high-priority interrupt (Channel 74): Triggered only by a correct // transfer event for isochronous and double-buffer bulk transfer to reach // the highest possible transfer rate. -void USB_HP_IRQHandler(void) -{ +void USB_HP_IRQHandler(void) { tud_int_handler(0); } // USB low-priority interrupt (Channel 75): Triggered by all USB events // (Correct transfer, USB reset, etc.). The firmware has to check the // interrupt source before serving the interrupt. -void USB_LP_IRQHandler(void) -{ +void USB_LP_IRQHandler(void) { tud_int_handler(0); } // USB wakeup interrupt (Channel 76): Triggered by the wakeup event from the USB // Suspend mode. -void USBWakeUp_RMP_IRQHandler(void) -{ +void USBWakeUp_RMP_IRQHandler(void) { tud_int_handler(0); } @@ -62,69 +60,11 @@ void USBWakeUp_RMP_IRQHandler(void) // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ -#define LED_PORT GPIOE -#define LED_PIN GPIO_PIN_9 -#define LED_STATE_ON 1 -#define BUTTON_PORT GPIOA -#define BUTTON_PIN GPIO_PIN_0 -#define BUTTON_STATE_ACTIVE 1 - - -/** - * @brief System Clock Configuration - * The system Clock is configured as follow : - * System Clock source = PLL (HSE) - * SYSCLK(Hz) = 72000000 - * HCLK(Hz) = 72000000 - * AHB Prescaler = 1 - * APB1 Prescaler = 2 - * APB2 Prescaler = 1 - * HSE Frequency(Hz) = 8000000 - * HSE PREDIV = 1 - * PLLMUL = RCC_PLL_MUL9 (9) - * Flash Latency(WS) = 2 - * @param None - * @retval None - */ -static void SystemClock_Config(void) -{ - RCC_ClkInitTypeDef RCC_ClkInitStruct; - RCC_OscInitTypeDef RCC_OscInitStruct; - RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit; - - /* Enable HSE Oscillator and activate PLL with HSE as source */ - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; - RCC_OscInitStruct.HSEState = RCC_HSE_ON; - RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; - RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; - RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; - HAL_RCC_OscConfig(&RCC_OscInitStruct); - - /* Configures the USB clock */ - HAL_RCCEx_GetPeriphCLKConfig(&RCC_PeriphClkInit); - RCC_PeriphClkInit.USBClockSelection = RCC_USBCLKSOURCE_PLL_DIV1_5; - HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit); - - /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 - clocks dividers */ - RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); - RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; - RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; - RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; - RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; - HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2); - - /* Enable Power Clock */ - __HAL_RCC_PWR_CLK_ENABLE(); -} - -void board_init(void) -{ +void board_init(void) { SystemClock_Config(); - #if CFG_TUSB_OS == OPT_OS_NONE + #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); #endif @@ -135,7 +75,7 @@ void board_init(void) // LED __HAL_RCC_GPIOE_CLK_ENABLE(); - GPIO_InitTypeDef GPIO_InitStruct; + GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = LED_PIN; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; @@ -167,50 +107,46 @@ 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) -{ - (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) { 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/stm32f3/family.cmake b/hw/bsp/stm32f3/family.cmake new file mode 100644 index 000000000..0a28e480b --- /dev/null +++ b/hw/bsp/stm32f3/family.cmake @@ -0,0 +1,110 @@ +include_guard() + +set(ST_FAMILY f3) +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-m3 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS STM32F3 CACHE INTERNAL "") + + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# 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}} + ) + 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 () + 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_STM32F3 ${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/stm32f3/boards/stm32f303disco/stm32f3xx_hal_conf.h b/hw/bsp/stm32f3/stm32f3xx_hal_conf.h similarity index 100% rename from hw/bsp/stm32f3/boards/stm32f303disco/stm32f3xx_hal_conf.h rename to hw/bsp/stm32f3/stm32f3xx_hal_conf.h diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index f17d30f06..c2c09a1fc 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -440,11 +440,15 @@ static void reset_core(dwc2_regs_t* dwc2) { } static bool phy_hs_supported(dwc2_regs_t* dwc2) { - // note: esp32 incorrect report its hs_phy_type as utmi + (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 return false; #else - return TUD_OPT_HIGH_SPEED && dwc2->ghwcfg2_bm.hs_phy_type != HS_PHY_TYPE_NONE; + return dwc2->ghwcfg2_bm.hs_phy_type != HS_PHY_TYPE_NONE; #endif } From b4d0303a26731d26a2a0cde9fc38201a88964ad9 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 23 Apr 2024 12:11:37 +0700 Subject: [PATCH 349/454] clang f4 --- .../stm32f1/FreeRTOSConfig/FreeRTOSConfig.h | 2 +- .../stm32f2/FreeRTOSConfig/FreeRTOSConfig.h | 149 ++++++++++++++++++ .../stm32f3/FreeRTOSConfig/FreeRTOSConfig.h | 149 ++++++++++++++++++ hw/bsp/stm32f4/family.cmake | 21 ++- 4 files changed, 309 insertions(+), 12 deletions(-) create mode 100644 hw/bsp/stm32f2/FreeRTOSConfig/FreeRTOSConfig.h create mode 100644 hw/bsp/stm32f3/FreeRTOSConfig/FreeRTOSConfig.h diff --git a/hw/bsp/stm32f1/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/stm32f1/FreeRTOSConfig/FreeRTOSConfig.h index d001411d9..c08a590a7 100644 --- a/hw/bsp/stm32f1/FreeRTOSConfig/FreeRTOSConfig.h +++ b/hw/bsp/stm32f1/FreeRTOSConfig/FreeRTOSConfig.h @@ -49,7 +49,7 @@ /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 -#define configENABLE_FPU 1 +#define configENABLE_FPU 0 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) diff --git a/hw/bsp/stm32f2/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/stm32f2/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..edbdba4b5 --- /dev/null +++ b/hw/bsp/stm32f2/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 "stm32f2xx.h" +#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< Date: Tue, 23 Apr 2024 12:22:40 +0700 Subject: [PATCH 350/454] clang f7, update cmsis f7 to fix startup bug --- .../stm32f7/boards/stm32f769disco/board.cmake | 2 +- hw/bsp/stm32f7/boards/stm32f769disco/board.mk | 2 ++ hw/bsp/stm32f7/family.cmake | 21 +++++++++---------- tools/get_deps.py | 2 +- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/hw/bsp/stm32f7/boards/stm32f769disco/board.cmake b/hw/bsp/stm32f7/boards/stm32f769disco/board.cmake index 62a157c58..329ada093 100644 --- a/hw/bsp/stm32f7/boards/stm32f769disco/board.cmake +++ b/hw/bsp/stm32f7/boards/stm32f769disco/board.cmake @@ -1,5 +1,5 @@ set(MCU_VARIANT stm32f769xx) -set(JLINK_DEVICE stm32f769xx) +set(JLINK_DEVICE stm32f769ni) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32F769ZITx_FLASH.ld) diff --git a/hw/bsp/stm32f7/boards/stm32f769disco/board.mk b/hw/bsp/stm32f7/boards/stm32f769disco/board.mk index a45af8cc0..705f1a633 100644 --- a/hw/bsp/stm32f7/boards/stm32f769disco/board.mk +++ b/hw/bsp/stm32f7/boards/stm32f769disco/board.mk @@ -11,5 +11,7 @@ CFLAGS += \ # Linker LD_FILE_GCC = $(BOARD_PATH)/STM32F769ZITx_FLASH.ld +JLINK_DEVICE = stm32f769ni + # flash target using on-board stlink flash: flash-stlink diff --git a/hw/bsp/stm32f7/family.cmake b/hw/bsp/stm32f7/family.cmake index 5b3bdf17e..be566f2eb 100644 --- a/hw/bsp/stm32f7/family.cmake +++ b/hw/bsp/stm32f7/family.cmake @@ -1,9 +1,5 @@ include_guard() -if (NOT BOARD) - message(FATAL_ERROR "BOARD not specified") -endif () - set(ST_FAMILY f7) set(ST_PREFIX stm32${ST_FAMILY}xx) @@ -29,7 +25,10 @@ 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 @@ -52,10 +51,8 @@ function(add_board_target BOARD_TARGET) ${ST_CMSIS}/Include ${ST_HAL_DRIVER}/Inc ) - target_compile_options(${BOARD_TARGET} PUBLIC - ) - target_compile_definitions(${BOARD_TARGET} PUBLIC - ) + #target_compile_options(${BOARD_TARGET} PUBLIC) + #target_compile_definitions(${BOARD_TARGET} PUBLIC) update_board(${BOARD_TARGET}) @@ -63,9 +60,11 @@ function(add_board_target BOARD_TARGET) target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles - # nanolib - --specs=nosys.specs - --specs=nano.specs + --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 diff --git a/tools/get_deps.py b/tools/get_deps.py index e9b7b70d8..3e5c6728d 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -84,7 +84,7 @@ deps_optional = { '2615e866fa48fe1ff1af9e31c348813f2b19e7ec', 'stm32f4'], 'hw/mcu/st/cmsis_device_f7': ['https://github.com/STMicroelectronics/cmsis_device_f7.git', - 'fc676ef1ad177eb874eaa06444d3d75395fc51f4', + '25b0463439303b7a38f0d27b161f7d2f3c096e79', 'stm32f7'], 'hw/mcu/st/cmsis_device_g0': ['https://github.com/STMicroelectronics/cmsis_device_g0.git', '3a23e1224417f3f2d00300ecd620495e363f2094', From a42e34701f7a6693f106fb69044871570aa38f22 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 23 Apr 2024 12:29:56 +0700 Subject: [PATCH 351/454] fix stm board linker define stack before memory def --- .../boards/stm32f072eval/STM32F072VBTx_FLASH.ld | 12 ++++++------ .../boards/stm32f407blackvet/STM32F407VETx_FLASH.ld | 12 ++++++------ .../stm32h7/boards/daisyseed/stm32h750ibkx_flash.ld | 12 ++++++------ hw/bsp/stm32h7/boards/daisyseed/stm32h750ibkx_ram.ld | 12 ++++++------ hw/bsp/stm32h7/linker/stm32h723xx_flash.ld | 12 ++++++------ 5 files changed, 30 insertions(+), 30 deletions(-) diff --git a/hw/bsp/stm32f0/boards/stm32f072eval/STM32F072VBTx_FLASH.ld b/hw/bsp/stm32f0/boards/stm32f072eval/STM32F072VBTx_FLASH.ld index 581613a5f..0eaf15186 100644 --- a/hw/bsp/stm32f0/boards/stm32f072eval/STM32F072VBTx_FLASH.ld +++ b/hw/bsp/stm32f0/boards/stm32f072eval/STM32F072VBTx_FLASH.ld @@ -27,12 +27,6 @@ /* Entry Point */ ENTRY(Reset_Handler) -/* Highest address of the user mode stack */ -_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ - -_Min_Heap_Size = 0x200 ; /* required amount of heap */ -_Min_Stack_Size = 0x400 ; /* required amount of stack */ - /* Memories definition */ MEMORY { @@ -40,6 +34,12 @@ MEMORY FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 128K } +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200 ; /* required amount of heap */ +_Min_Stack_Size = 0x400 ; /* required amount of stack */ + /* Sections */ SECTIONS { diff --git a/hw/bsp/stm32f4/boards/stm32f407blackvet/STM32F407VETx_FLASH.ld b/hw/bsp/stm32f4/boards/stm32f407blackvet/STM32F407VETx_FLASH.ld index 6dec5543a..2e97c633a 100644 --- a/hw/bsp/stm32f4/boards/stm32f407blackvet/STM32F407VETx_FLASH.ld +++ b/hw/bsp/stm32f4/boards/stm32f407blackvet/STM32F407VETx_FLASH.ld @@ -28,12 +28,6 @@ /* Entry Point */ ENTRY(Reset_Handler) -/* Highest address of the user mode stack */ -_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ - -_Min_Heap_Size = 0x200 ; /* required amount of heap */ -_Min_Stack_Size = 0x400 ; /* required amount of stack */ - /* Memories definition */ MEMORY { @@ -42,6 +36,12 @@ MEMORY FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K } +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200 ; /* required amount of heap */ +_Min_Stack_Size = 0x400 ; /* required amount of stack */ + /* Sections */ SECTIONS { diff --git a/hw/bsp/stm32h7/boards/daisyseed/stm32h750ibkx_flash.ld b/hw/bsp/stm32h7/boards/daisyseed/stm32h750ibkx_flash.ld index 3588ada5b..e2bde9338 100644 --- a/hw/bsp/stm32h7/boards/daisyseed/stm32h750ibkx_flash.ld +++ b/hw/bsp/stm32h7/boards/daisyseed/stm32h750ibkx_flash.ld @@ -34,12 +34,6 @@ /* Entry Point */ ENTRY(Reset_Handler) -/* 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 = 0x2000 ; /* required amount of heap */ -_Min_Stack_Size = 0x4000 ; /* required amount of stack */ - /* Specify the memory areas */ MEMORY { @@ -51,6 +45,12 @@ MEMORY ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K } +/* 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 = 0x2000 ; /* required amount of heap */ +_Min_Stack_Size = 0x4000 ; /* required amount of stack */ + /* Define output sections */ SECTIONS { diff --git a/hw/bsp/stm32h7/boards/daisyseed/stm32h750ibkx_ram.ld b/hw/bsp/stm32h7/boards/daisyseed/stm32h750ibkx_ram.ld index 16f48b10a..03d9aaba3 100644 --- a/hw/bsp/stm32h7/boards/daisyseed/stm32h750ibkx_ram.ld +++ b/hw/bsp/stm32h7/boards/daisyseed/stm32h750ibkx_ram.ld @@ -34,12 +34,6 @@ /* Entry Point */ ENTRY(Reset_Handler) -/* Highest address of the user mode stack */ -_estack = ORIGIN(DTCMRAM) + LENGTH(DTCMRAM); /* end of RAM */ -/* Generate a link error if heap and stack don't fit into RAM */ -_Min_Heap_Size = 0x2000 ; /* required amount of heap */ -_Min_Stack_Size = 0x4000 ; /* required amount of stack */ - /* Specify the memory areas */ MEMORY { @@ -50,6 +44,12 @@ MEMORY ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K } +/* Highest address of the user mode stack */ +_estack = ORIGIN(DTCMRAM) + LENGTH(DTCMRAM); /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x2000 ; /* required amount of heap */ +_Min_Stack_Size = 0x4000 ; /* required amount of stack */ + /* Define output sections */ SECTIONS { diff --git a/hw/bsp/stm32h7/linker/stm32h723xx_flash.ld b/hw/bsp/stm32h7/linker/stm32h723xx_flash.ld index 05e0d4e26..b779c0d35 100644 --- a/hw/bsp/stm32h7/linker/stm32h723xx_flash.ld +++ b/hw/bsp/stm32h7/linker/stm32h723xx_flash.ld @@ -34,12 +34,6 @@ /* Entry Point */ ENTRY(Reset_Handler) -/* 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 */ - /* Specify the memory areas */ MEMORY { @@ -51,6 +45,12 @@ MEMORY RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 16K } +/* 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 { From 16e099a9f946661ad7924b95b1345d7e1bf9dc69 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 23 Apr 2024 12:38:55 +0700 Subject: [PATCH 352/454] integrate msp430 to build cmake --- .../{cmake_arm.yml => build_cmake.yml} | 74 +++++++++++++++---- .github/workflows/build_msp430.yml | 71 ------------------ 2 files changed, 59 insertions(+), 86 deletions(-) rename .github/workflows/{cmake_arm.yml => build_cmake.yml} (80%) delete mode 100644 .github/workflows/build_msp430.yml diff --git a/.github/workflows/cmake_arm.yml b/.github/workflows/build_cmake.yml similarity index 80% rename from .github/workflows/cmake_arm.yml rename to .github/workflows/build_cmake.yml index 8eb1e3f74..ee6d83992 100644 --- a/.github/workflows/cmake_arm.yml +++ b/.github/workflows/build_cmake.yml @@ -1,4 +1,4 @@ -name: CMake ARM +name: Build CMake on: workflow_dispatch: @@ -10,7 +10,7 @@ on: - 'hw/**' - 'test/hil/**' - 'tools/get_deps.py' - - '.github/workflows/cmake_arm.yml' + - '.github/workflows/build_cmake.yml' pull_request: branches: [ master ] paths: @@ -20,7 +20,7 @@ on: - 'hw/**' - 'test/hil/**' - 'tools/get_deps.py' - - '.github/workflows/cmake_arm.yml' + - '.github/workflows/build_cmake.yml' concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} @@ -156,6 +156,14 @@ 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 @@ -173,19 +181,9 @@ jobs: wget --progress=dot:mega $TOOLCHAIN_URL -O toolchain.tar.xz tar -C ~/cache/toolchain -xaf toolchain.tar.xz - - name: Set Toolchain Path - run: echo >> $GITHUB_PATH `echo ~/cache/toolchain/*/bin` - - - 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 + - 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 }} @@ -194,6 +192,52 @@ jobs: env: PICO_SDK_PATH: ${{ github.workspace }}/pico-sdk + # --------------------------------------- + # Build ARM with Clang + # --------------------------------------- + msp430-gcc: + runs-on: ubuntu-latest + 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@v3 + 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 }} -DCMAKE_BUILD_TYPE=MinSizeRel + # --------------------------------------- # Hardware in the loop (HIL) # Current self-hosted instance is running on an RPI4. For attached hardware checkout hil_pi4.json diff --git a/.github/workflows/build_msp430.yml b/.github/workflows/build_msp430.yml deleted file mode 100644 index 95d212708..000000000 --- a/.github/workflows/build_msp430.yml +++ /dev/null @@ -1,71 +0,0 @@ -name: Build MSP430 - -on: - workflow_dispatch: - push: - paths: - - 'src/**' - - 'examples/**' - - 'lib/**' - - 'hw/**' - - 'tools/get_deps.py' - - '.github/workflows/build_msp430.yml' - pull_request: - branches: [ master ] - paths: - - 'src/**' - - 'examples/**' - - 'lib/**' - - 'hw/**' - - 'tools/get_deps.py' - - '.github/workflows/build_msp430.yml' - -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - build-msp430: - runs-on: ubuntu-latest - 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@v3 - 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.bz2 - tar -C ~/cache/toolchain -xaf toolchain.tar.bz2 - - - name: Set Toolchain Path - run: | - echo >> $GITHUB_PATH `echo ~/cache/toolchain/*/bin` - sudo apt install -y ninja-build - - - name: Build - run: | - python3 tools/get_deps.py ${{ matrix.family }} - python tools/build_cmake.py ${{ matrix.family }} -DCMAKE_BUILD_TYPE=MinSizeRel From 9e7046cbf117d46a7949836ece0432ecf542e9fc Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 23 Apr 2024 12:57:57 +0700 Subject: [PATCH 353/454] more stm32 linker fix --- .../boards/stm32f439nucleo/STM32F439ZITX_FLASH.ld | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/hw/bsp/stm32f4/boards/stm32f439nucleo/STM32F439ZITX_FLASH.ld b/hw/bsp/stm32f4/boards/stm32f439nucleo/STM32F439ZITX_FLASH.ld index 2dc277c77..cc098b533 100644 --- a/hw/bsp/stm32f4/boards/stm32f439nucleo/STM32F439ZITX_FLASH.ld +++ b/hw/bsp/stm32f4/boards/stm32f439nucleo/STM32F439ZITX_FLASH.ld @@ -36,12 +36,6 @@ /* Entry Point */ ENTRY(Reset_Handler) -/* Highest address of the user mode stack */ -_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ - -_Min_Heap_Size = 0x200; /* required amount of heap */ -_Min_Stack_Size = 0x400; /* required amount of stack */ - /* Memories definition */ MEMORY { @@ -50,6 +44,12 @@ MEMORY FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 2048K } +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + /* Sections */ SECTIONS { From 75d376a439652eb4879c25694d9a4452cffc6bb4 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 23 Apr 2024 15:56:22 +0700 Subject: [PATCH 354/454] clang g0, g4 --- .../stm32g0/FreeRTOSConfig/FreeRTOSConfig.h | 2 +- .../stm32g0b1nucleo/STM32G0B1RETx_FLASH.ld | 13 +-- hw/bsp/stm32g0/family.c | 1 - hw/bsp/stm32g0/family.cmake | 97 ++++++++++--------- .../stm32g474nucleo/STM32G474RETx_FLASH.ld | 12 +-- hw/bsp/stm32g4/family.c | 1 - hw/bsp/stm32g4/family.cmake | 12 ++- 7 files changed, 70 insertions(+), 68 deletions(-) diff --git a/hw/bsp/stm32g0/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/stm32g0/FreeRTOSConfig/FreeRTOSConfig.h index e1a7bb135..82cb0cdb3 100644 --- a/hw/bsp/stm32g0/FreeRTOSConfig/FreeRTOSConfig.h +++ b/hw/bsp/stm32g0/FreeRTOSConfig/FreeRTOSConfig.h @@ -49,7 +49,7 @@ /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 -#define configENABLE_FPU 1 +#define configENABLE_FPU 0 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) diff --git a/hw/bsp/stm32g0/boards/stm32g0b1nucleo/STM32G0B1RETx_FLASH.ld b/hw/bsp/stm32g0/boards/stm32g0b1nucleo/STM32G0B1RETx_FLASH.ld index 0f3fed096..b6fab16cf 100644 --- a/hw/bsp/stm32g0/boards/stm32g0b1nucleo/STM32G0B1RETx_FLASH.ld +++ b/hw/bsp/stm32g0/boards/stm32g0b1nucleo/STM32G0B1RETx_FLASH.ld @@ -52,12 +52,6 @@ /* Entry Point */ ENTRY(Reset_Handler) -/* Highest address of the user mode stack */ -_estack = ORIGIN(RAM) + LENGTH(RAM); /* 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 { @@ -65,6 +59,13 @@ RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 144K FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K } +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* 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 { diff --git a/hw/bsp/stm32g0/family.c b/hw/bsp/stm32g0/family.c index 3730e44aa..d1635be12 100644 --- a/hw/bsp/stm32g0/family.c +++ b/hw/bsp/stm32g0/family.c @@ -179,7 +179,6 @@ void SysTick_Handler(void) { uint32_t board_millis(void) { return system_ticks; } - #endif void HardFault_Handler(void) { diff --git a/hw/bsp/stm32g0/family.cmake b/hw/bsp/stm32g0/family.cmake index 0a9779022..b6838c619 100644 --- a/hw/bsp/stm32g0/family.cmake +++ b/hw/bsp/stm32g0/family.cmake @@ -1,9 +1,5 @@ include_guard() -if (NOT BOARD) - message(FATAL_ERROR "BOARD not specified") -endif () - set(ST_FAMILY g0) set(ST_PREFIX stm32${ST_FAMILY}xx) @@ -26,52 +22,57 @@ set(FAMILY_MCUS STM32G0 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_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) - set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) + if (TARGET ${BOARD_TARGET}) + return() + 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_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_gpio.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_dma.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 - ) + # 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) - update_board(${BOARD_TARGET}) + set(LD_FILE_Clang ${LD_FILE_GNU}) + set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--script=${LD_FILE_GNU}" - -nostartfiles - # nanolib - --specs=nosys.specs - --specs=nano.specs - ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--config=${LD_FILE_IAR}" - ) - 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_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_gpio.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_dma.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() @@ -112,5 +113,5 @@ function(family_configure_example TARGET RTOS) # Flashing family_flash_stlink(${TARGET}) - #family_flash_jlink(${TARGET}) + family_flash_jlink(${TARGET}) endfunction() diff --git a/hw/bsp/stm32g4/boards/stm32g474nucleo/STM32G474RETx_FLASH.ld b/hw/bsp/stm32g4/boards/stm32g474nucleo/STM32G474RETx_FLASH.ld index 8ba23a5b8..25a104bc2 100644 --- a/hw/bsp/stm32g4/boards/stm32g474nucleo/STM32G474RETx_FLASH.ld +++ b/hw/bsp/stm32g4/boards/stm32g474nucleo/STM32G474RETx_FLASH.ld @@ -52,12 +52,6 @@ /* Entry Point */ ENTRY(Reset_Handler) -/* Highest address of the user mode stack */ -_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ - -_Min_Heap_Size = 0x1000 ; /* required amount of heap */ -_Min_Stack_Size = 0x1000 ; /* required amount of stack */ - /* Memories definition */ MEMORY { @@ -65,6 +59,12 @@ MEMORY FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K } +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x1000 ; /* required amount of heap */ +_Min_Stack_Size = 0x1000 ; /* required amount of stack */ + /* Sections */ SECTIONS { diff --git a/hw/bsp/stm32g4/family.c b/hw/bsp/stm32g4/family.c index 39be0249a..2259cb9e2 100644 --- a/hw/bsp/stm32g4/family.c +++ b/hw/bsp/stm32g4/family.c @@ -209,7 +209,6 @@ void SysTick_Handler(void) { uint32_t board_millis(void) { return system_ticks; } - #endif void HardFault_Handler(void) { diff --git a/hw/bsp/stm32g4/family.cmake b/hw/bsp/stm32g4/family.cmake index 15a834a00..f15b994b9 100644 --- a/hw/bsp/stm32g4/family.cmake +++ b/hw/bsp/stm32g4/family.cmake @@ -1,9 +1,5 @@ include_guard() -if (NOT BOARD) - message(FATAL_ERROR "BOARD not specified") -endif () - set(ST_FAMILY g4) set(ST_PREFIX stm32${ST_FAMILY}xx) @@ -32,7 +28,10 @@ function(add_board_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 @@ -59,9 +58,12 @@ function(add_board_target BOARD_TARGET) target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles - # nanolib --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}" From d6814a3f3af5124894bc204e880845ada52b80d8 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 23 Apr 2024 16:23:27 +0700 Subject: [PATCH 355/454] clang support for H5 --- hw/bsp/stm32g4/family.cmake | 1 + hw/bsp/stm32h5/family.cmake | 15 +- hw/bsp/stm32h5/linker/STM32H503xx_FLASH.ld | 188 +++++++++++++++++++++ hw/bsp/stm32h5/linker/STM32H523xx_FLASH.ld | 187 ++++++++++++++++++++ hw/bsp/stm32h5/linker/STM32H533xx_FLASH.ld | 187 ++++++++++++++++++++ hw/bsp/stm32h5/linker/STM32H562xx_FLASH.ld | 187 ++++++++++++++++++++ hw/bsp/stm32h5/linker/STM32H563xx_FLASH.ld | 187 ++++++++++++++++++++ hw/bsp/stm32h5/linker/STM32H573xx_FLASH.ld | 187 ++++++++++++++++++++ tools/get_deps.py | 2 +- 9 files changed, 1133 insertions(+), 8 deletions(-) create mode 100644 hw/bsp/stm32h5/linker/STM32H503xx_FLASH.ld create mode 100644 hw/bsp/stm32h5/linker/STM32H523xx_FLASH.ld create mode 100644 hw/bsp/stm32h5/linker/STM32H533xx_FLASH.ld create mode 100644 hw/bsp/stm32h5/linker/STM32H562xx_FLASH.ld create mode 100644 hw/bsp/stm32h5/linker/STM32H563xx_FLASH.ld create mode 100644 hw/bsp/stm32h5/linker/STM32H573xx_FLASH.ld diff --git a/hw/bsp/stm32g4/family.cmake b/hw/bsp/stm32g4/family.cmake index f15b994b9..4217e4be6 100644 --- a/hw/bsp/stm32g4/family.cmake +++ b/hw/bsp/stm32g4/family.cmake @@ -52,6 +52,7 @@ function(add_board_target BOARD_TARGET) ${ST_CMSIS}/Include ${ST_HAL_DRIVER}/Inc ) + update_board(${BOARD_TARGET}) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") diff --git a/hw/bsp/stm32h5/family.cmake b/hw/bsp/stm32h5/family.cmake index e5850f38d..94900f416 100644 --- a/hw/bsp/stm32h5/family.cmake +++ b/hw/bsp/stm32h5/family.cmake @@ -1,9 +1,5 @@ include_guard() -if (NOT BOARD) - message(FATAL_ERROR "BOARD not specified") -endif () - set(ST_FAMILY h5) set(ST_PREFIX stm32${ST_FAMILY}xx) @@ -32,11 +28,13 @@ function(add_board_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_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) string(REPLACE "stm32h" "STM32H" MCU_VARIANT_UPPER ${MCU_VARIANT}) - set(LD_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/linker/${MCU_VARIANT_UPPER}_FLASH.ld) + set(LD_FILE_GNU ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/linker/${MCU_VARIANT_UPPER}_FLASH.ld) + 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 @@ -65,9 +63,12 @@ function(add_board_target BOARD_TARGET) target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles - # nanolib --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}" diff --git a/hw/bsp/stm32h5/linker/STM32H503xx_FLASH.ld b/hw/bsp/stm32h5/linker/STM32H503xx_FLASH.ld new file mode 100644 index 000000000..abf618233 --- /dev/null +++ b/hw/bsp/stm32h5/linker/STM32H503xx_FLASH.ld @@ -0,0 +1,188 @@ +/* + ****************************************************************************** + ** + ** @file : LinkerScript.ld + ** + ** @author : Auto-generated by STM32CubeIDE + ** + ** @brief : Linker script for STM32H503xx Device from STM32H5 series + ** 128Kbytes FLASH + ** 32Kbytes 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) 2023 STMicroelectronics. + ** All rights reserved. + ** + ** This software is licensed under terms that can be found in the LICENSE file + ** in the root directory of this software component. + ** If no LICENSE file comes with this software, it is provided AS-IS. + ** + ****************************************************************************** + */ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K + FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 128K +} + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .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 into "FLASH" Rom type memory */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >FLASH + + .ARM : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >FLASH + + .preinit_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >FLASH + + .init_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >FLASH + + .fini_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + . = 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" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/stm32h5/linker/STM32H523xx_FLASH.ld b/hw/bsp/stm32h5/linker/STM32H523xx_FLASH.ld new file mode 100644 index 000000000..b799892c6 --- /dev/null +++ b/hw/bsp/stm32h5/linker/STM32H523xx_FLASH.ld @@ -0,0 +1,187 @@ +/* + ****************************************************************************** + ** + ** @file : LinkerScript.ld + ** + ** @author : Auto-generated by STM32CubeIDE + ** + ** @brief : Linker script for STM32H523xx Device from STM32H5 series + ** 512Kbytes FLASH + ** 272Kbytes 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) 2023 STMicroelectronics. + ** All rights reserved. + ** + ** This software is licensed under terms that can be found in the LICENSE file + ** in the root directory of this software component. + ** If no LICENSE file comes with this software, it is provided AS-IS. + ** + ****************************************************************************** + */ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 272K + FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K +} + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .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 into "FLASH" Rom type memory */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >FLASH + + .ARM : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >FLASH + + .preinit_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >FLASH + + .init_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >FLASH + + .fini_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + . = 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" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/stm32h5/linker/STM32H533xx_FLASH.ld b/hw/bsp/stm32h5/linker/STM32H533xx_FLASH.ld new file mode 100644 index 000000000..dece7a003 --- /dev/null +++ b/hw/bsp/stm32h5/linker/STM32H533xx_FLASH.ld @@ -0,0 +1,187 @@ +/* + ****************************************************************************** + ** + ** @file : LinkerScript.ld + ** + ** @author : Auto-generated by STM32CubeIDE + ** + ** @brief : Linker script for STM32H533xx Device from STM32H5 series + ** 512Kbytes FLASH + ** 272Kbytes 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) 2023 STMicroelectronics. + ** All rights reserved. + ** + ** This software is licensed under terms that can be found in the LICENSE file + ** in the root directory of this software component. + ** If no LICENSE file comes with this software, it is provided AS-IS. + ** + ****************************************************************************** + */ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 272K + FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K +} + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .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 into "FLASH" Rom type memory */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >FLASH + + .ARM : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >FLASH + + .preinit_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >FLASH + + .init_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >FLASH + + .fini_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + . = 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" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/stm32h5/linker/STM32H562xx_FLASH.ld b/hw/bsp/stm32h5/linker/STM32H562xx_FLASH.ld new file mode 100644 index 000000000..aee2774a4 --- /dev/null +++ b/hw/bsp/stm32h5/linker/STM32H562xx_FLASH.ld @@ -0,0 +1,187 @@ +/* + ****************************************************************************** + ** + ** @file : LinkerScript.ld + ** + ** @author : Auto-generated by STM32CubeIDE + ** + ** @brief : Linker script for STM32H562xx Device from STM32H5 series + ** 2048Kbytes FLASH + ** 640Kbytes 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) 2023 STMicroelectronics. + ** All rights reserved. + ** + ** This software is licensed under terms that can be found in the LICENSE file + ** in the root directory of this software component. + ** If no LICENSE file comes with this software, it is provided AS-IS. + ** + ****************************************************************************** + */ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 640K + FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 2048K +} + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .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 into "FLASH" Rom type memory */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >FLASH + + .ARM : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >FLASH + + .preinit_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >FLASH + + .init_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >FLASH + + .fini_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + . = 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" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/stm32h5/linker/STM32H563xx_FLASH.ld b/hw/bsp/stm32h5/linker/STM32H563xx_FLASH.ld new file mode 100644 index 000000000..129ed5170 --- /dev/null +++ b/hw/bsp/stm32h5/linker/STM32H563xx_FLASH.ld @@ -0,0 +1,187 @@ +/* + ****************************************************************************** + ** + ** @file : LinkerScript.ld + ** + ** @author : Auto-generated by STM32CubeIDE + ** + ** @brief : Linker script for STM32H563xx Device from STM32H5 series + ** 2048Kbytes FLASH + ** 640Kbytes 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) 2023 STMicroelectronics. + ** All rights reserved. + ** + ** This software is licensed under terms that can be found in the LICENSE file + ** in the root directory of this software component. + ** If no LICENSE file comes with this software, it is provided AS-IS. + ** + ****************************************************************************** + */ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 640K + FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 2048K +} + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .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 into "FLASH" Rom type memory */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >FLASH + + .ARM : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >FLASH + + .preinit_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >FLASH + + .init_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >FLASH + + .fini_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + . = 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" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/stm32h5/linker/STM32H573xx_FLASH.ld b/hw/bsp/stm32h5/linker/STM32H573xx_FLASH.ld new file mode 100644 index 000000000..eb98f3163 --- /dev/null +++ b/hw/bsp/stm32h5/linker/STM32H573xx_FLASH.ld @@ -0,0 +1,187 @@ +/* + ****************************************************************************** + ** + ** @file : LinkerScript.ld + ** + ** @author : Auto-generated by STM32CubeIDE + ** + ** @brief : Linker script for STM32H573xx Device from STM32H5 series + ** 2048Kbytes FLASH + ** 640Kbytes 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) 2023 STMicroelectronics. + ** All rights reserved. + ** + ** This software is licensed under terms that can be found in the LICENSE file + ** in the root directory of this software component. + ** If no LICENSE file comes with this software, it is provided AS-IS. + ** + ****************************************************************************** + */ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 640K + FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 2048K +} + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .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 into "FLASH" Rom type memory */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >FLASH + + .ARM : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >FLASH + + .preinit_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >FLASH + + .init_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >FLASH + + .fini_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + . = 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" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/tools/get_deps.py b/tools/get_deps.py index 3e5c6728d..4d405ffff 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -96,7 +96,7 @@ deps_optional = { '60dc2c913203dc8629dc233d4384dcc41c91e77f', 'stm32h7'], 'hw/mcu/st/cmsis_device_h5': ['https://github.com/STMicroelectronics/cmsis_device_h5.git', - '62b2cb0fbfe10c5791ee469bbde7b397c2fea8f5', + 'cd2d1d579743de57b88ccaf61a968b9c05848ffc', 'stm32h5'], 'hw/mcu/st/cmsis_device_l0': ['https://github.com/STMicroelectronics/cmsis_device_l0.git', '06748ca1f93827befdb8b794402320d94d02004f', From 999177fe394e080f7266fd72f07ae9b6708feeba Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 23 Apr 2024 22:36:00 +0700 Subject: [PATCH 356/454] - fix g4 clang linker - clang work with l0 --- .../stm32f0/FreeRTOSConfig/FreeRTOSConfig.h | 2 +- .../b_g474e_dpow1/STM32G474RETx_FLASH.ld | 12 +- .../stm32g491nucleo/STM32G491RETX_FLASH.ld | 12 +- .../stm32l0/FreeRTOSConfig/FreeRTOSConfig.h | 149 ++++++++++++++++++ .../stm32l0/boards/stm32l052dap52/board.cmake | 10 ++ .../boards/stm32l0538disco/board.cmake | 10 ++ hw/bsp/stm32l0/family.c | 58 +++---- hw/bsp/stm32l0/family.cmake | 114 ++++++++++++++ tools/get_deps.py | 2 +- 9 files changed, 316 insertions(+), 53 deletions(-) create mode 100644 hw/bsp/stm32l0/FreeRTOSConfig/FreeRTOSConfig.h create mode 100644 hw/bsp/stm32l0/boards/stm32l052dap52/board.cmake create mode 100644 hw/bsp/stm32l0/boards/stm32l0538disco/board.cmake create mode 100644 hw/bsp/stm32l0/family.cmake diff --git a/hw/bsp/stm32f0/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/stm32f0/FreeRTOSConfig/FreeRTOSConfig.h index b9a54b9b3..37e7e0943 100644 --- a/hw/bsp/stm32f0/FreeRTOSConfig/FreeRTOSConfig.h +++ b/hw/bsp/stm32f0/FreeRTOSConfig/FreeRTOSConfig.h @@ -49,7 +49,7 @@ /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 -#define configENABLE_FPU 1 +#define configENABLE_FPU 0 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) diff --git a/hw/bsp/stm32g4/boards/b_g474e_dpow1/STM32G474RETx_FLASH.ld b/hw/bsp/stm32g4/boards/b_g474e_dpow1/STM32G474RETx_FLASH.ld index 8ba23a5b8..25a104bc2 100644 --- a/hw/bsp/stm32g4/boards/b_g474e_dpow1/STM32G474RETx_FLASH.ld +++ b/hw/bsp/stm32g4/boards/b_g474e_dpow1/STM32G474RETx_FLASH.ld @@ -52,12 +52,6 @@ /* Entry Point */ ENTRY(Reset_Handler) -/* Highest address of the user mode stack */ -_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ - -_Min_Heap_Size = 0x1000 ; /* required amount of heap */ -_Min_Stack_Size = 0x1000 ; /* required amount of stack */ - /* Memories definition */ MEMORY { @@ -65,6 +59,12 @@ MEMORY FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K } +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x1000 ; /* required amount of heap */ +_Min_Stack_Size = 0x1000 ; /* required amount of stack */ + /* Sections */ SECTIONS { diff --git a/hw/bsp/stm32g4/boards/stm32g491nucleo/STM32G491RETX_FLASH.ld b/hw/bsp/stm32g4/boards/stm32g491nucleo/STM32G491RETX_FLASH.ld index f5553a112..88ef666c7 100644 --- a/hw/bsp/stm32g4/boards/stm32g491nucleo/STM32G491RETX_FLASH.ld +++ b/hw/bsp/stm32g4/boards/stm32g491nucleo/STM32G491RETX_FLASH.ld @@ -35,12 +35,6 @@ /* Entry Point */ ENTRY(Reset_Handler) -/* Highest address of the user mode stack */ -_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ - -_Min_Heap_Size = 0x200; /* required amount of heap */ -_Min_Stack_Size = 0x400; /* required amount of stack */ - /* Memories definition */ MEMORY { @@ -48,6 +42,12 @@ MEMORY FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K } +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + /* Sections */ SECTIONS { diff --git a/hw/bsp/stm32l0/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/stm32l0/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..37e7e0943 --- /dev/null +++ b/hw/bsp/stm32l0/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 "stm32f0xx.h" +#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 2 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< Date: Tue, 23 Apr 2024 22:45:36 +0700 Subject: [PATCH 357/454] clang l4 --- hw/bsp/stm32l4/family.cmake | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/hw/bsp/stm32l4/family.cmake b/hw/bsp/stm32l4/family.cmake index 9b06a64d4..c42b6a8d7 100644 --- a/hw/bsp/stm32l4/family.cmake +++ b/hw/bsp/stm32l4/family.cmake @@ -1,9 +1,5 @@ include_guard() -if (NOT BOARD) - message(FATAL_ERROR "BOARD not specified") -endif () - set(ST_FAMILY l4) set(ST_PREFIX stm32${ST_FAMILY}xx) @@ -29,7 +25,10 @@ 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 @@ -52,10 +51,8 @@ function(add_board_target BOARD_TARGET) ${ST_CMSIS}/Include ${ST_HAL_DRIVER}/Inc ) - target_compile_options(${BOARD_TARGET} PUBLIC - ) - target_compile_definitions(${BOARD_TARGET} PUBLIC - ) +# target_compile_options(${BOARD_TARGET} PUBLIC) +# target_compile_definitions(${BOARD_TARGET} PUBLIC) update_board(${BOARD_TARGET}) @@ -63,9 +60,11 @@ function(add_board_target BOARD_TARGET) target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles - # nanolib - --specs=nosys.specs - --specs=nano.specs + --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 From 0e06c4cfdf1cb57f1c71fd3de022eda9310f6f35 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 24 Apr 2024 00:03:13 +0700 Subject: [PATCH 358/454] clang u5, also bump up cmsis u5 version --- .../stm32u5/boards/stm32u575eval/board.cmake | 2 - .../boards/stm32u575nucleo/board.cmake | 2 - .../stm32u5a5nucleo/STM32U5A5ZJTXQ_FLASH.ld | 12 +- hw/bsp/stm32u5/family.cmake | 16 +- hw/bsp/stm32u5/linker/STM32U535xx_FLASH.ld | 167 ++++++++++++++++ hw/bsp/stm32u5/linker/STM32U545xx_FLASH.ld | 167 ++++++++++++++++ hw/bsp/stm32u5/linker/STM32U575xx_FLASH.ld | 185 ++++++++++++++++++ hw/bsp/stm32u5/linker/STM32U585xx_FLASH.ld | 185 ++++++++++++++++++ hw/bsp/stm32u5/linker/STM32U595xx_FLASH.ld | 168 ++++++++++++++++ hw/bsp/stm32u5/linker/STM32U599xx_FLASH.ld | 168 ++++++++++++++++ hw/bsp/stm32u5/linker/STM32U5A9xx_FLASH.ld | 168 ++++++++++++++++ hw/bsp/stm32u5/linker/STM32U5F7xx_FLASH.ld | 168 ++++++++++++++++ hw/bsp/stm32u5/linker/STM32U5F9xx_FLASH.ld | 168 ++++++++++++++++ hw/bsp/stm32u5/linker/STM32U5G7xx_FLASH.ld | 168 ++++++++++++++++ hw/bsp/stm32u5/linker/STM32U5G9xx_FLASH.ld | 168 ++++++++++++++++ tools/get_deps.py | 2 +- 16 files changed, 1898 insertions(+), 16 deletions(-) create mode 100644 hw/bsp/stm32u5/linker/STM32U535xx_FLASH.ld create mode 100644 hw/bsp/stm32u5/linker/STM32U545xx_FLASH.ld create mode 100644 hw/bsp/stm32u5/linker/STM32U575xx_FLASH.ld create mode 100644 hw/bsp/stm32u5/linker/STM32U585xx_FLASH.ld create mode 100644 hw/bsp/stm32u5/linker/STM32U595xx_FLASH.ld create mode 100644 hw/bsp/stm32u5/linker/STM32U599xx_FLASH.ld create mode 100644 hw/bsp/stm32u5/linker/STM32U5A9xx_FLASH.ld create mode 100644 hw/bsp/stm32u5/linker/STM32U5F7xx_FLASH.ld create mode 100644 hw/bsp/stm32u5/linker/STM32U5F9xx_FLASH.ld create mode 100644 hw/bsp/stm32u5/linker/STM32U5G7xx_FLASH.ld create mode 100644 hw/bsp/stm32u5/linker/STM32U5G9xx_FLASH.ld diff --git a/hw/bsp/stm32u5/boards/stm32u575eval/board.cmake b/hw/bsp/stm32u5/boards/stm32u575eval/board.cmake index 57ba85c71..dc2f42d94 100644 --- a/hw/bsp/stm32u5/boards/stm32u575eval/board.cmake +++ b/hw/bsp/stm32u5/boards/stm32u575eval/board.cmake @@ -1,8 +1,6 @@ set(MCU_VARIANT stm32u575xx) set(JLINK_DEVICE stm32u575ai) -set(LD_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/linker/STM32U575xx_FLASH.ld) - function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32U575xx diff --git a/hw/bsp/stm32u5/boards/stm32u575nucleo/board.cmake b/hw/bsp/stm32u5/boards/stm32u575nucleo/board.cmake index 73bd10033..76285c08f 100644 --- a/hw/bsp/stm32u5/boards/stm32u575nucleo/board.cmake +++ b/hw/bsp/stm32u5/boards/stm32u575nucleo/board.cmake @@ -1,8 +1,6 @@ set(MCU_VARIANT stm32u575xx) set(JLINK_DEVICE stm32u575zi) -set(LD_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/linker/STM32U575xx_FLASH.ld) - function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32U575xx diff --git a/hw/bsp/stm32u5/boards/stm32u5a5nucleo/STM32U5A5ZJTXQ_FLASH.ld b/hw/bsp/stm32u5/boards/stm32u5a5nucleo/STM32U5A5ZJTXQ_FLASH.ld index 8aa68a6a6..2d1028cbe 100644 --- a/hw/bsp/stm32u5/boards/stm32u5a5nucleo/STM32U5A5ZJTXQ_FLASH.ld +++ b/hw/bsp/stm32u5/boards/stm32u5a5nucleo/STM32U5A5ZJTXQ_FLASH.ld @@ -35,12 +35,6 @@ /* Entry Point */ ENTRY(Reset_Handler) -/* Highest address of the user mode stack */ -_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ - -_Min_Heap_Size = 0x200; /* required amount of heap */ -_Min_Stack_Size = 0x400; /* required amount of stack */ - /* Memories definition */ MEMORY { @@ -49,6 +43,12 @@ MEMORY FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 4096K } +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + /* Sections */ SECTIONS { diff --git a/hw/bsp/stm32u5/family.cmake b/hw/bsp/stm32u5/family.cmake index cde1df5ca..d3cb78abf 100644 --- a/hw/bsp/stm32u5/family.cmake +++ b/hw/bsp/stm32u5/family.cmake @@ -1,9 +1,5 @@ include_guard() -if (NOT BOARD) - message(FATAL_ERROR "BOARD not specified") -endif () - set(ST_FAMILY u5) set(ST_PREFIX stm32${ST_FAMILY}xx) @@ -29,7 +25,14 @@ 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 @@ -57,9 +60,12 @@ function(add_board_target BOARD_TARGET) target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles - # nanolib --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}" diff --git a/hw/bsp/stm32u5/linker/STM32U535xx_FLASH.ld b/hw/bsp/stm32u5/linker/STM32U535xx_FLASH.ld new file mode 100644 index 000000000..6ac1479a3 --- /dev/null +++ b/hw/bsp/stm32u5/linker/STM32U535xx_FLASH.ld @@ -0,0 +1,167 @@ +/* +****************************************************************************** +** +** File : LinkerScript.ld +** +** Author : STM32CubeIDE +** +** Abstract : Linker script for STM32U535xE Device from STM32U5 series +** 512Kbytes FLASH +** 272Kbytes 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) 2022 STMicroelectronics. +** All rights reserved. +** +** This software is licensed under terms that can be found in the LICENSE file +** in the root directory of this software component. +** If no LICENSE file comes with this software, it is provided AS-IS. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K + SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K +} + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200 ; /* required amount of heap */ +_Min_Stack_Size = 0x400 ; /* required amount of stack */ + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + KEEP(*(.isr_vector)) /* Startup code */ + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + *(.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)) + + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + } >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 into "RAM" Ram type memory */ + .data : + { + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + .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) + + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/stm32u5/linker/STM32U545xx_FLASH.ld b/hw/bsp/stm32u5/linker/STM32U545xx_FLASH.ld new file mode 100644 index 000000000..ce370c643 --- /dev/null +++ b/hw/bsp/stm32u5/linker/STM32U545xx_FLASH.ld @@ -0,0 +1,167 @@ +/* +****************************************************************************** +** +** File : LinkerScript.ld +** +** Author : STM32CubeIDE +** +** Abstract : Linker script for STM32U545xE Device from STM32U5 series +** 512Kbytes FLASH +** 272Kbytes 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) 2022 STMicroelectronics. +** All rights reserved. +** +** This software is licensed under terms that can be found in the LICENSE file +** in the root directory of this software component. +** If no LICENSE file comes with this software, it is provided AS-IS. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K + SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K +} + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200 ; /* required amount of heap */ +_Min_Stack_Size = 0x400 ; /* required amount of stack */ + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + KEEP(*(.isr_vector)) /* Startup code */ + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + *(.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)) + + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + } >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 into "RAM" Ram type memory */ + .data : + { + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + .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) + + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/stm32u5/linker/STM32U575xx_FLASH.ld b/hw/bsp/stm32u5/linker/STM32U575xx_FLASH.ld new file mode 100644 index 000000000..b24c533de --- /dev/null +++ b/hw/bsp/stm32u5/linker/STM32U575xx_FLASH.ld @@ -0,0 +1,185 @@ +/* +****************************************************************************** +** +** File : LinkerScript.ld +** +** Author : Auto-generated by STM32CubeIDE +** +** Abstract : Linker script for STM32U575xx Device from STM32U5 series +** 2048Kbytes ROM +** 784Kbytes 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) 2021 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) + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 768K + ROM (rx) : ORIGIN = 0x08000000, LENGTH = 2048K + SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K +} + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Sections */ +SECTIONS +{ + /* The startup code into "ROM" Rom type memory */ + .isr_vector : + { + . = ALIGN(8); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(8); + } >ROM + + /* The program code and other data into "ROM" Rom type memory */ + .text : + { + . = ALIGN(8); + *(.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(8); + _etext = .; /* define a global symbols at end of code */ + } >ROM + + /* Constant data into "ROM" Rom type memory */ + .rodata : + { + . = ALIGN(8); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(8); + } >ROM + + .ARM.extab : { + . = ALIGN(8); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(8); + } >ROM + + .ARM : { + . = ALIGN(8); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(8); + } >ROM + + .preinit_array : + { + . = ALIGN(8); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(8); + } >ROM + + .init_array : + { + . = ALIGN(8); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(8); + } >ROM + + .fini_array : + { + . = ALIGN(8); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(8); + } >ROM + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(8); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(8); + _edata = .; /* define a global symbol at data end */ + + } >RAM AT> ROM + + /* Uninitialized data section into "RAM" Ram type memory */ + . = ALIGN(8); + .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(8); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/stm32u5/linker/STM32U585xx_FLASH.ld b/hw/bsp/stm32u5/linker/STM32U585xx_FLASH.ld new file mode 100644 index 000000000..15b8054bc --- /dev/null +++ b/hw/bsp/stm32u5/linker/STM32U585xx_FLASH.ld @@ -0,0 +1,185 @@ +/* +****************************************************************************** +** +** File : LinkerScript.ld +** +** Author : Auto-generated by STM32CubeIDE +** +** Abstract : Linker script for STM32U585xx Device from STM32U5 series +** 2048Kbytes ROM +** 784Kbytes 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) 2021 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) + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 768K + ROM (rx) : ORIGIN = 0x08000000, LENGTH = 2048K + SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K +} + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Sections */ +SECTIONS +{ + /* The startup code into "ROM" Rom type memory */ + .isr_vector : + { + . = ALIGN(8); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(8); + } >ROM + + /* The program code and other data into "ROM" Rom type memory */ + .text : + { + . = ALIGN(8); + *(.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(8); + _etext = .; /* define a global symbols at end of code */ + } >ROM + + /* Constant data into "ROM" Rom type memory */ + .rodata : + { + . = ALIGN(8); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(8); + } >ROM + + .ARM.extab : { + . = ALIGN(8); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(8); + } >ROM + + .ARM : { + . = ALIGN(8); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(8); + } >ROM + + .preinit_array : + { + . = ALIGN(8); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(8); + } >ROM + + .init_array : + { + . = ALIGN(8); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(8); + } >ROM + + .fini_array : + { + . = ALIGN(8); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(8); + } >ROM + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(8); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(8); + _edata = .; /* define a global symbol at data end */ + + } >RAM AT> ROM + + /* Uninitialized data section into "RAM" Ram type memory */ + . = ALIGN(8); + .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(8); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/stm32u5/linker/STM32U595xx_FLASH.ld b/hw/bsp/stm32u5/linker/STM32U595xx_FLASH.ld new file mode 100644 index 000000000..100ee14a5 --- /dev/null +++ b/hw/bsp/stm32u5/linker/STM32U595xx_FLASH.ld @@ -0,0 +1,168 @@ +/* +****************************************************************************** +** +** File : LinkerScript.ld +** +** Author : STM32CubeIDE +** +** Abstract : Linker script for STM32U595xJ Device from STM32U5 series +** 4096Kbytes FLASH +** 2528Kbytes 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) 2021 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) + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 2496K + SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 4096K +} + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200 ; /* required amount of heap */ +_Min_Stack_Size = 0x400 ; /* required amount of stack */ + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + KEEP(*(.isr_vector)) /* Startup code */ + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + *(.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)) + + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + } >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 into "RAM" Ram type memory */ + .data : + { + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + .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) + + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/stm32u5/linker/STM32U599xx_FLASH.ld b/hw/bsp/stm32u5/linker/STM32U599xx_FLASH.ld new file mode 100644 index 000000000..55997bf40 --- /dev/null +++ b/hw/bsp/stm32u5/linker/STM32U599xx_FLASH.ld @@ -0,0 +1,168 @@ +/* +****************************************************************************** +** +** File : LinkerScript.ld +** +** Author : STM32CubeIDE +** +** Abstract : Linker script for STM32U599xJ Device from STM32U5 series +** 4096Kbytes FLASH +** 2528Kbytes 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) 2021 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) + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 2496K + SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 4096K +} + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200 ; /* required amount of heap */ +_Min_Stack_Size = 0x400 ; /* required amount of stack */ + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + KEEP(*(.isr_vector)) /* Startup code */ + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + *(.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)) + + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + } >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 into "RAM" Ram type memory */ + .data : + { + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + .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) + + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/stm32u5/linker/STM32U5A9xx_FLASH.ld b/hw/bsp/stm32u5/linker/STM32U5A9xx_FLASH.ld new file mode 100644 index 000000000..a5f7d3405 --- /dev/null +++ b/hw/bsp/stm32u5/linker/STM32U5A9xx_FLASH.ld @@ -0,0 +1,168 @@ +/* +****************************************************************************** +** +** File : LinkerScript.ld +** +** Author : STM32CubeIDE +** +** Abstract : Linker script for STM32U5A9xJ Device from STM32U5 series +** 4096Kbytes FLASH +** 2528Kbytes 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) 2021 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) + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 2496K + SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 4096K +} + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200 ; /* required amount of heap */ +_Min_Stack_Size = 0x400 ; /* required amount of stack */ + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + KEEP(*(.isr_vector)) /* Startup code */ + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + *(.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)) + + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + } >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 into "RAM" Ram type memory */ + .data : + { + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + .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) + + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/stm32u5/linker/STM32U5F7xx_FLASH.ld b/hw/bsp/stm32u5/linker/STM32U5F7xx_FLASH.ld new file mode 100644 index 000000000..bb9953440 --- /dev/null +++ b/hw/bsp/stm32u5/linker/STM32U5F7xx_FLASH.ld @@ -0,0 +1,168 @@ +/* +****************************************************************************** +** +** File : LinkerScript.ld +** +** Author : STM32CubeIDE +** +** Abstract : Linker script for STM32U5F7xJ Device from STM32U5 series +** 4096Kbytes FLASH +** 2528Kbytes 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) 2023 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) + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 2496K + SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 4096K +} + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200 ; /* required amount of heap */ +_Min_Stack_Size = 0x400 ; /* required amount of stack */ + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + KEEP(*(.isr_vector)) /* Startup code */ + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + *(.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)) + + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + } >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 into "RAM" Ram type memory */ + .data : + { + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + .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) + + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/stm32u5/linker/STM32U5F9xx_FLASH.ld b/hw/bsp/stm32u5/linker/STM32U5F9xx_FLASH.ld new file mode 100644 index 000000000..d8f1f4c5f --- /dev/null +++ b/hw/bsp/stm32u5/linker/STM32U5F9xx_FLASH.ld @@ -0,0 +1,168 @@ +/* +****************************************************************************** +** +** File : LinkerScript.ld +** +** Author : STM32CubeIDE +** +** Abstract : Linker script for STM32U5F9xJ Device from STM32U5 series +** 4096Kbytes FLASH +** 2528Kbytes 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) 2023 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) + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 2496K + SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 4096K +} + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200 ; /* required amount of heap */ +_Min_Stack_Size = 0x400 ; /* required amount of stack */ + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + KEEP(*(.isr_vector)) /* Startup code */ + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + *(.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)) + + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + } >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 into "RAM" Ram type memory */ + .data : + { + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + .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) + + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/stm32u5/linker/STM32U5G7xx_FLASH.ld b/hw/bsp/stm32u5/linker/STM32U5G7xx_FLASH.ld new file mode 100644 index 000000000..d02d6ebf1 --- /dev/null +++ b/hw/bsp/stm32u5/linker/STM32U5G7xx_FLASH.ld @@ -0,0 +1,168 @@ +/* +****************************************************************************** +** +** File : LinkerScript.ld +** +** Author : STM32CubeIDE +** +** Abstract : Linker script for STM32U5G7xJ Device from STM32U5 series +** 4096Kbytes FLASH +** 2528Kbytes 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) 2023 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) + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 2496K + SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 4096K +} + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200 ; /* required amount of heap */ +_Min_Stack_Size = 0x400 ; /* required amount of stack */ + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + KEEP(*(.isr_vector)) /* Startup code */ + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + *(.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)) + + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + } >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 into "RAM" Ram type memory */ + .data : + { + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + .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) + + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/stm32u5/linker/STM32U5G9xx_FLASH.ld b/hw/bsp/stm32u5/linker/STM32U5G9xx_FLASH.ld new file mode 100644 index 000000000..1b072fdd4 --- /dev/null +++ b/hw/bsp/stm32u5/linker/STM32U5G9xx_FLASH.ld @@ -0,0 +1,168 @@ +/* +****************************************************************************** +** +** File : LinkerScript.ld +** +** Author : STM32CubeIDE +** +** Abstract : Linker script for STM32U5G9xJ Device from STM32U5 series +** 4096Kbytes FLASH +** 2528Kbytes 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) 2023 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) + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 2496K + SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 4096K +} + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200 ; /* required amount of heap */ +_Min_Stack_Size = 0x400 ; /* required amount of stack */ + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + KEEP(*(.isr_vector)) /* Startup code */ + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + *(.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)) + + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + } >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 into "RAM" Ram type memory */ + .data : + { + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + .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) + + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/tools/get_deps.py b/tools/get_deps.py index 70c161132..bf6ef8c00 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -111,7 +111,7 @@ deps_optional = { 'd922865fc0326a102c26211c44b8e42f52c1e53d', 'stm32l5'], 'hw/mcu/st/cmsis_device_u5': ['https://github.com/STMicroelectronics/cmsis_device_u5.git', - '06d7edade7167b0eafdd550bf77cfc4fa98eae2e', + '5ad9797c54ec3e55eff770fc9b3cd4a1aefc1309', 'stm32u5'], 'hw/mcu/st/cmsis_device_wb': ['https://github.com/STMicroelectronics/cmsis_device_wb.git', '9c5d1920dd9fabbe2548e10561d63db829bb744f', From 60f39f7b1e32a1a081f6e850eafebbce4068ecf1 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 24 Apr 2024 00:33:56 +0700 Subject: [PATCH 359/454] fix l4 linker with clang --- .../boards/stm32l4p5nucleo/STM32L4P5ZGTX_FLASH.ld | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/hw/bsp/stm32l4/boards/stm32l4p5nucleo/STM32L4P5ZGTX_FLASH.ld b/hw/bsp/stm32l4/boards/stm32l4p5nucleo/STM32L4P5ZGTX_FLASH.ld index 02c07dd74..6a2eaa0f7 100644 --- a/hw/bsp/stm32l4/boards/stm32l4p5nucleo/STM32L4P5ZGTX_FLASH.ld +++ b/hw/bsp/stm32l4/boards/stm32l4p5nucleo/STM32L4P5ZGTX_FLASH.ld @@ -52,12 +52,6 @@ /* Entry Point */ ENTRY(Reset_Handler) -/* Highest address of the user mode stack */ -_estack = ORIGIN(RAM) + 0x0001FFFF; /* end of "SRAM1" Ram type memory */ - -_Min_Heap_Size = 0x200; /* required amount of heap */ -_Min_Stack_Size = 0x400; /* required amount of stack */ - /* Memories definition */ MEMORY { @@ -65,6 +59,12 @@ MEMORY ROM (rx) : ORIGIN = 0x08000000, LENGTH = 1024K } +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + 0x0001FFFF; /* end of "SRAM1" Ram type memory */ + +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + /* Sections */ SECTIONS { From 36e07093b8a62f6b899451562f232638b2b80415 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 24 Apr 2024 11:24:27 +0700 Subject: [PATCH 360/454] fix samd linker with clang: cannot self-check defined symbol with lld e.g `STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : 0x1000` --> STACK_SIZE = 0 --- hw/bsp/fomu/fomu.ld | 2 +- .../boards/cynthion_d11/samd11d14am_flash.ld | 2 +- .../samd11_xplained/samd11d14am_flash.ld | 2 +- .../boards/atsamd21_xpro/samd21j18a_flash.ld | 2 +- .../circuitplayground_express.ld | 2 +- .../boards/curiosity_nano/samd21g17a_flash.ld | 2 +- .../boards/cynthion_d21/samd21g18a_flash.ld | 2 +- .../feather_m0_express/feather_m0_express.ld | 2 +- .../boards/itsybitsy_m0/itsybitsy_m0.ld | 2 +- .../metro_m0_express/metro_m0_express.ld | 2 +- hw/bsp/samd21/boards/qtpy/qtpy.ld | 2 +- .../boards/seeeduino_xiao/seeeduino_xiao.ld | 2 +- .../sparkfun_samd21_mini_usb.ld | 2 +- hw/bsp/samd21/boards/trinket_m0/trinket_m0.ld | 2 +- hw/bsp/samd21/family.cmake | 93 ++++++++++--------- .../feather_m4_express/feather_m4_express.ld | 2 +- .../boards/itsybitsy_m4/itsybitsy_m4.ld | 2 +- .../metro_m4_express/metro_m4_express.ld | 2 +- hw/bsp/samd51/boards/pybadge/pybadge.ld | 2 +- hw/bsp/samd51/boards/pyportal/pyportal.ld | 2 +- hw/bsp/samd51/family.cmake | 90 +++++++++--------- .../boards/d5035_01/same51j19a_flash.ld | 2 +- .../same54_xplained/same54p20a_flash.ld | 2 +- .../boards/same54_xplained/same54p20a_sram.ld | 2 +- hw/bsp/samg55xplained/samg55j19_flash.ld | 2 +- .../boards/atsaml21_xpro/saml21j18b_flash.ld | 2 +- .../boards/saml22_feather/saml22_feather.ld | 2 +- .../boards/sensorwatch_m0/sensorwatch_m0.ld | 2 +- 28 files changed, 120 insertions(+), 115 deletions(-) diff --git a/hw/bsp/fomu/fomu.ld b/hw/bsp/fomu/fomu.ld index 13278d2ad..0b0cf2612 100644 --- a/hw/bsp/fomu/fomu.ld +++ b/hw/bsp/fomu/fomu.ld @@ -11,7 +11,7 @@ MEMORY { } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x2000; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x2000; /* Section Definitions */ SECTIONS diff --git a/hw/bsp/samd11/boards/cynthion_d11/samd11d14am_flash.ld b/hw/bsp/samd11/boards/cynthion_d11/samd11d14am_flash.ld index f175e6504..57e7f8904 100644 --- a/hw/bsp/samd11/boards/cynthion_d11/samd11d14am_flash.ld +++ b/hw/bsp/samd11/boards/cynthion_d11/samd11d14am_flash.ld @@ -40,7 +40,7 @@ MEMORY } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x400; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x400; /* Section Definitions */ SECTIONS diff --git a/hw/bsp/samd11/boards/samd11_xplained/samd11d14am_flash.ld b/hw/bsp/samd11/boards/samd11_xplained/samd11d14am_flash.ld index 9e12acec8..75d880f62 100644 --- a/hw/bsp/samd11/boards/samd11_xplained/samd11d14am_flash.ld +++ b/hw/bsp/samd11/boards/samd11_xplained/samd11d14am_flash.ld @@ -40,7 +40,7 @@ MEMORY } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x400; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x400; /* Section Definitions */ SECTIONS diff --git a/hw/bsp/samd21/boards/atsamd21_xpro/samd21j18a_flash.ld b/hw/bsp/samd21/boards/atsamd21_xpro/samd21j18a_flash.ld index e2f93416d..d9b086f9c 100644 --- a/hw/bsp/samd21/boards/atsamd21_xpro/samd21j18a_flash.ld +++ b/hw/bsp/samd21/boards/atsamd21_xpro/samd21j18a_flash.ld @@ -40,7 +40,7 @@ MEMORY } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x2000; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x2000; /* Section Definitions */ SECTIONS diff --git a/hw/bsp/samd21/boards/circuitplayground_express/circuitplayground_express.ld b/hw/bsp/samd21/boards/circuitplayground_express/circuitplayground_express.ld index f0c93340c..ce7aff80b 100644 --- a/hw/bsp/samd21/boards/circuitplayground_express/circuitplayground_express.ld +++ b/hw/bsp/samd21/boards/circuitplayground_express/circuitplayground_express.ld @@ -40,7 +40,7 @@ MEMORY } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x2000; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x2000; ENTRY(Reset_Handler) diff --git a/hw/bsp/samd21/boards/curiosity_nano/samd21g17a_flash.ld b/hw/bsp/samd21/boards/curiosity_nano/samd21g17a_flash.ld index 153f0cbb9..e03a4ce60 100644 --- a/hw/bsp/samd21/boards/curiosity_nano/samd21g17a_flash.ld +++ b/hw/bsp/samd21/boards/curiosity_nano/samd21g17a_flash.ld @@ -40,7 +40,7 @@ MEMORY } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x1000; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x1000; /* Section Definitions */ SECTIONS diff --git a/hw/bsp/samd21/boards/cynthion_d21/samd21g18a_flash.ld b/hw/bsp/samd21/boards/cynthion_d21/samd21g18a_flash.ld index ecb6b8523..95d71b9e3 100644 --- a/hw/bsp/samd21/boards/cynthion_d21/samd21g18a_flash.ld +++ b/hw/bsp/samd21/boards/cynthion_d21/samd21g18a_flash.ld @@ -40,7 +40,7 @@ MEMORY } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x2000; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x2000; /* Section Definitions */ SECTIONS diff --git a/hw/bsp/samd21/boards/feather_m0_express/feather_m0_express.ld b/hw/bsp/samd21/boards/feather_m0_express/feather_m0_express.ld index f0c93340c..ce7aff80b 100644 --- a/hw/bsp/samd21/boards/feather_m0_express/feather_m0_express.ld +++ b/hw/bsp/samd21/boards/feather_m0_express/feather_m0_express.ld @@ -40,7 +40,7 @@ MEMORY } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x2000; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x2000; ENTRY(Reset_Handler) diff --git a/hw/bsp/samd21/boards/itsybitsy_m0/itsybitsy_m0.ld b/hw/bsp/samd21/boards/itsybitsy_m0/itsybitsy_m0.ld index f0c93340c..ce7aff80b 100644 --- a/hw/bsp/samd21/boards/itsybitsy_m0/itsybitsy_m0.ld +++ b/hw/bsp/samd21/boards/itsybitsy_m0/itsybitsy_m0.ld @@ -40,7 +40,7 @@ MEMORY } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x2000; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x2000; ENTRY(Reset_Handler) diff --git a/hw/bsp/samd21/boards/metro_m0_express/metro_m0_express.ld b/hw/bsp/samd21/boards/metro_m0_express/metro_m0_express.ld index f0c93340c..ce7aff80b 100644 --- a/hw/bsp/samd21/boards/metro_m0_express/metro_m0_express.ld +++ b/hw/bsp/samd21/boards/metro_m0_express/metro_m0_express.ld @@ -40,7 +40,7 @@ MEMORY } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x2000; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x2000; ENTRY(Reset_Handler) diff --git a/hw/bsp/samd21/boards/qtpy/qtpy.ld b/hw/bsp/samd21/boards/qtpy/qtpy.ld index f0c93340c..ce7aff80b 100644 --- a/hw/bsp/samd21/boards/qtpy/qtpy.ld +++ b/hw/bsp/samd21/boards/qtpy/qtpy.ld @@ -40,7 +40,7 @@ MEMORY } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x2000; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x2000; ENTRY(Reset_Handler) diff --git a/hw/bsp/samd21/boards/seeeduino_xiao/seeeduino_xiao.ld b/hw/bsp/samd21/boards/seeeduino_xiao/seeeduino_xiao.ld index cf11c4c35..0d0c4e6c4 100644 --- a/hw/bsp/samd21/boards/seeeduino_xiao/seeeduino_xiao.ld +++ b/hw/bsp/samd21/boards/seeeduino_xiao/seeeduino_xiao.ld @@ -40,7 +40,7 @@ MEMORY } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x2000; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x2000; ENTRY(Reset_Handler) diff --git a/hw/bsp/samd21/boards/sparkfun_samd21_mini_usb/sparkfun_samd21_mini_usb.ld b/hw/bsp/samd21/boards/sparkfun_samd21_mini_usb/sparkfun_samd21_mini_usb.ld index f5d2ad151..0754a8e9c 100644 --- a/hw/bsp/samd21/boards/sparkfun_samd21_mini_usb/sparkfun_samd21_mini_usb.ld +++ b/hw/bsp/samd21/boards/sparkfun_samd21_mini_usb/sparkfun_samd21_mini_usb.ld @@ -40,7 +40,7 @@ MEMORY } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x2000; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x2000; ENTRY(Reset_Handler) diff --git a/hw/bsp/samd21/boards/trinket_m0/trinket_m0.ld b/hw/bsp/samd21/boards/trinket_m0/trinket_m0.ld index f0c93340c..ce7aff80b 100644 --- a/hw/bsp/samd21/boards/trinket_m0/trinket_m0.ld +++ b/hw/bsp/samd21/boards/trinket_m0/trinket_m0.ld @@ -40,7 +40,7 @@ MEMORY } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x2000; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x2000; ENTRY(Reset_Handler) diff --git a/hw/bsp/samd21/family.cmake b/hw/bsp/samd21/family.cmake index 616c8ae45..540a0ee33 100644 --- a/hw/bsp/samd21/family.cmake +++ b/hw/bsp/samd21/family.cmake @@ -17,55 +17,57 @@ set(OPENOCD_OPTION "-f interface/cmsis-dap.cfg -c \"transport select swd\" -f ta #------------------------------------ # only need to be built ONCE for all examples function(add_board_target BOARD_TARGET) - if (NOT TARGET ${BOARD_TARGET}) - 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 () + if (TARGET ${BOARD_TARGET}) + return() + endif () - if (NOT DEFINED STARTUP_FILE_${CMAKE_C_COMPILER_ID}) - set(STARTUP_FILE_GNU ${SDK_DIR}/gcc/gcc/startup_samd21.c) - set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) - 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 () - add_library(${BOARD_TARGET} STATIC - ${SDK_DIR}/gcc/system_samd21.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 - ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + if (NOT DEFINED STARTUP_FILE_GNU) + set(STARTUP_FILE_GNU ${SDK_DIR}/gcc/gcc/startup_samd21.c) + endif () + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + + add_library(${BOARD_TARGET} STATIC + ${SDK_DIR}/gcc/system_samd21.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 + ${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 + ${SDK_DIR}/CMSIS/Include + ) + target_compile_definitions(${BOARD_TARGET} PUBLIC CONF_DFLL_OVERWRITE_CALIBRATION=0) + + 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 - ${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 - ${SDK_DIR}/CMSIS/Include + 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}" ) - target_compile_definitions(${BOARD_TARGET} PUBLIC CONF_DFLL_OVERWRITE_CALIBRATION=0) - - 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() @@ -104,6 +106,7 @@ function(family_configure_example TARGET RTOS) 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/boards/feather_m4_express/feather_m4_express.ld b/hw/bsp/samd51/boards/feather_m4_express/feather_m4_express.ld index f1a021d75..1408c3018 100644 --- a/hw/bsp/samd51/boards/feather_m4_express/feather_m4_express.ld +++ b/hw/bsp/samd51/boards/feather_m4_express/feather_m4_express.ld @@ -42,7 +42,7 @@ MEMORY } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0xC000; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0xC000; ENTRY(Reset_Handler) diff --git a/hw/bsp/samd51/boards/itsybitsy_m4/itsybitsy_m4.ld b/hw/bsp/samd51/boards/itsybitsy_m4/itsybitsy_m4.ld index f1a021d75..1408c3018 100644 --- a/hw/bsp/samd51/boards/itsybitsy_m4/itsybitsy_m4.ld +++ b/hw/bsp/samd51/boards/itsybitsy_m4/itsybitsy_m4.ld @@ -42,7 +42,7 @@ MEMORY } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0xC000; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0xC000; ENTRY(Reset_Handler) 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 index f1a021d75..1408c3018 100644 --- a/hw/bsp/samd51/boards/metro_m4_express/metro_m4_express.ld +++ b/hw/bsp/samd51/boards/metro_m4_express/metro_m4_express.ld @@ -42,7 +42,7 @@ MEMORY } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0xC000; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0xC000; ENTRY(Reset_Handler) diff --git a/hw/bsp/samd51/boards/pybadge/pybadge.ld b/hw/bsp/samd51/boards/pybadge/pybadge.ld index f1a021d75..1408c3018 100644 --- a/hw/bsp/samd51/boards/pybadge/pybadge.ld +++ b/hw/bsp/samd51/boards/pybadge/pybadge.ld @@ -42,7 +42,7 @@ MEMORY } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0xC000; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0xC000; ENTRY(Reset_Handler) diff --git a/hw/bsp/samd51/boards/pyportal/pyportal.ld b/hw/bsp/samd51/boards/pyportal/pyportal.ld index f1a021d75..1408c3018 100644 --- a/hw/bsp/samd51/boards/pyportal/pyportal.ld +++ b/hw/bsp/samd51/boards/pyportal/pyportal.ld @@ -42,7 +42,7 @@ MEMORY } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0xC000; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0xC000; ENTRY(Reset_Handler) diff --git a/hw/bsp/samd51/family.cmake b/hw/bsp/samd51/family.cmake index 8d88cf947..3ddd2e290 100644 --- a/hw/bsp/samd51/family.cmake +++ b/hw/bsp/samd51/family.cmake @@ -18,54 +18,56 @@ set(OPENOCD_OPTION "-f interface/cmsis-dap.cfg -c \"transport select swd\" -c \" #------------------------------------ # only need to be built ONCE for all examples function(add_board_target BOARD_TARGET) - if (NOT TARGET ${BOARD_TARGET}) - 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 () + if (TARGET ${BOARD_TARGET}) + return() + endif () - if (NOT DEFINED STARTUP_FILE_${CMAKE_C_COMPILER_ID}) - set(STARTUP_FILE_GNU ${SDK_DIR}/gcc/gcc/startup_samd51.c) - set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) - 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 () - add_library(${BOARD_TARGET} STATIC - ${SDK_DIR}/gcc/system_samd51.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}} + if (NOT DEFINED STARTUP_FILE_GNU) + set(STARTUP_FILE_GNU ${SDK_DIR}/gcc/gcc/startup_samd51.c) + endif () + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + + add_library(${BOARD_TARGET} STATIC + ${SDK_DIR}/gcc/system_samd51.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}/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 ) - 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 + 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}" ) - - 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/same5x/boards/d5035_01/same51j19a_flash.ld b/hw/bsp/same5x/boards/d5035_01/same51j19a_flash.ld index a8dd44336..486043f22 100644 --- a/hw/bsp/same5x/boards/d5035_01/same51j19a_flash.ld +++ b/hw/bsp/same5x/boards/d5035_01/same51j19a_flash.ld @@ -42,7 +42,7 @@ MEMORY } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x1000; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x1000; /* Section Definitions */ SECTIONS diff --git a/hw/bsp/same5x/boards/same54_xplained/same54p20a_flash.ld b/hw/bsp/same5x/boards/same54_xplained/same54p20a_flash.ld index 1f427a066..7a7f1be46 100644 --- a/hw/bsp/same5x/boards/same54_xplained/same54p20a_flash.ld +++ b/hw/bsp/same5x/boards/same54_xplained/same54p20a_flash.ld @@ -42,7 +42,7 @@ MEMORY } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x10000; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x10000; /* Section Definitions */ SECTIONS diff --git a/hw/bsp/same5x/boards/same54_xplained/same54p20a_sram.ld b/hw/bsp/same5x/boards/same54_xplained/same54p20a_sram.ld index e6e33ec48..c768f9c9a 100644 --- a/hw/bsp/same5x/boards/same54_xplained/same54p20a_sram.ld +++ b/hw/bsp/same5x/boards/same54_xplained/same54p20a_sram.ld @@ -41,7 +41,7 @@ MEMORY } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x10000; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x10000; /* Section Definitions */ SECTIONS diff --git a/hw/bsp/samg55xplained/samg55j19_flash.ld b/hw/bsp/samg55xplained/samg55j19_flash.ld index 21c0b5bcd..a222b919b 100644 --- a/hw/bsp/samg55xplained/samg55j19_flash.ld +++ b/hw/bsp/samg55xplained/samg55j19_flash.ld @@ -40,7 +40,7 @@ MEMORY } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x0400; +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; diff --git a/hw/bsp/saml2x/boards/atsaml21_xpro/saml21j18b_flash.ld b/hw/bsp/saml2x/boards/atsaml21_xpro/saml21j18b_flash.ld index 7f6b7fa99..48cacd526 100644 --- a/hw/bsp/saml2x/boards/atsaml21_xpro/saml21j18b_flash.ld +++ b/hw/bsp/saml2x/boards/atsaml21_xpro/saml21j18b_flash.ld @@ -40,7 +40,7 @@ MEMORY } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x2000; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x2000; /* Section Definitions */ SECTIONS diff --git a/hw/bsp/saml2x/boards/saml22_feather/saml22_feather.ld b/hw/bsp/saml2x/boards/saml22_feather/saml22_feather.ld index 156c3e7e4..372107ff8 100644 --- a/hw/bsp/saml2x/boards/saml22_feather/saml22_feather.ld +++ b/hw/bsp/saml2x/boards/saml22_feather/saml22_feather.ld @@ -40,7 +40,7 @@ MEMORY } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x2000; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x2000; ENTRY(Reset_Handler) diff --git a/hw/bsp/saml2x/boards/sensorwatch_m0/sensorwatch_m0.ld b/hw/bsp/saml2x/boards/sensorwatch_m0/sensorwatch_m0.ld index 156c3e7e4..372107ff8 100644 --- a/hw/bsp/saml2x/boards/sensorwatch_m0/sensorwatch_m0.ld +++ b/hw/bsp/saml2x/boards/sensorwatch_m0/sensorwatch_m0.ld @@ -40,7 +40,7 @@ MEMORY } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x2000; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x2000; ENTRY(Reset_Handler) From 41f9fd651333021842c9e674f30e02b7a551e22a Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 24 Apr 2024 11:38:33 +0700 Subject: [PATCH 361/454] update clion metadata --- .idea/cmake.xml | 31 +++++++++++++++------------ .idea/runConfigurations/kl25.xml | 2 +- .idea/runConfigurations/lpc1857.xml | 2 +- .idea/runConfigurations/lpc4088.xml | 2 +- .idea/runConfigurations/lpc54628.xml | 2 +- .idea/runConfigurations/lpc55s69.xml | 2 +- .idea/runConfigurations/mcx947.xml | 2 +- .idea/runConfigurations/nrf52840.xml | 2 +- .idea/runConfigurations/nrf5340.xml | 2 +- .idea/runConfigurations/ra4m1.xml | 2 +- .idea/runConfigurations/ra6m1.xml | 2 +- .idea/runConfigurations/ra6m5.xml | 2 +- .idea/runConfigurations/rp2040.xml | 2 +- .idea/runConfigurations/rt1010.xml | 2 +- .idea/runConfigurations/rt1060.xml | 2 +- .idea/runConfigurations/samd21g18.xml | 2 +- .idea/runConfigurations/samd51j19.xml | 2 +- .idea/runConfigurations/stlink.xml | 2 +- .idea/runConfigurations/stm32g474.xml | 2 +- .idea/runConfigurations/stm32h743.xml | 4 ++-- .idea/runConfigurations/uno_r4.xml | 2 +- 21 files changed, 38 insertions(+), 35 deletions(-) diff --git a/.idea/cmake.xml b/.idea/cmake.xml index c361e237d..22199b103 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -3,8 +3,8 @@ - - + + @@ -42,10 +42,10 @@ - - + + - + @@ -53,11 +53,13 @@ + - - + + + @@ -65,17 +67,19 @@ + + - - - - - - + + + + + + @@ -84,7 +88,6 @@ - diff --git a/.idea/runConfigurations/kl25.xml b/.idea/runConfigurations/kl25.xml index 5c7bd73ba..96c208dde 100644 --- a/.idea/runConfigurations/kl25.xml +++ b/.idea/runConfigurations/kl25.xml @@ -1,5 +1,5 @@ - + diff --git a/.idea/runConfigurations/lpc1857.xml b/.idea/runConfigurations/lpc1857.xml index 2c059206e..a4764b9d6 100644 --- a/.idea/runConfigurations/lpc1857.xml +++ b/.idea/runConfigurations/lpc1857.xml @@ -1,5 +1,5 @@ - + diff --git a/.idea/runConfigurations/lpc4088.xml b/.idea/runConfigurations/lpc4088.xml index 524279eaa..9da975ef3 100644 --- a/.idea/runConfigurations/lpc4088.xml +++ b/.idea/runConfigurations/lpc4088.xml @@ -1,5 +1,5 @@ - + diff --git a/.idea/runConfigurations/lpc54628.xml b/.idea/runConfigurations/lpc54628.xml index f4ea323d7..0c3877e94 100644 --- a/.idea/runConfigurations/lpc54628.xml +++ b/.idea/runConfigurations/lpc54628.xml @@ -1,5 +1,5 @@ - + diff --git a/.idea/runConfigurations/lpc55s69.xml b/.idea/runConfigurations/lpc55s69.xml index 8a2cc00a7..2fa127d33 100644 --- a/.idea/runConfigurations/lpc55s69.xml +++ b/.idea/runConfigurations/lpc55s69.xml @@ -1,5 +1,5 @@ - + diff --git a/.idea/runConfigurations/mcx947.xml b/.idea/runConfigurations/mcx947.xml index 528e5b644..12180a996 100644 --- a/.idea/runConfigurations/mcx947.xml +++ b/.idea/runConfigurations/mcx947.xml @@ -1,5 +1,5 @@ - + diff --git a/.idea/runConfigurations/nrf52840.xml b/.idea/runConfigurations/nrf52840.xml index e24651de9..8e48a2b97 100644 --- a/.idea/runConfigurations/nrf52840.xml +++ b/.idea/runConfigurations/nrf52840.xml @@ -1,5 +1,5 @@ - + diff --git a/.idea/runConfigurations/nrf5340.xml b/.idea/runConfigurations/nrf5340.xml index 56cad71b1..646f2d38c 100644 --- a/.idea/runConfigurations/nrf5340.xml +++ b/.idea/runConfigurations/nrf5340.xml @@ -1,5 +1,5 @@ - + diff --git a/.idea/runConfigurations/ra4m1.xml b/.idea/runConfigurations/ra4m1.xml index 83a2efe56..72bc63d9b 100644 --- a/.idea/runConfigurations/ra4m1.xml +++ b/.idea/runConfigurations/ra4m1.xml @@ -1,5 +1,5 @@ - + diff --git a/.idea/runConfigurations/ra6m1.xml b/.idea/runConfigurations/ra6m1.xml index c30757ed8..ca8c7245a 100644 --- a/.idea/runConfigurations/ra6m1.xml +++ b/.idea/runConfigurations/ra6m1.xml @@ -1,5 +1,5 @@ - + diff --git a/.idea/runConfigurations/ra6m5.xml b/.idea/runConfigurations/ra6m5.xml index e252debbb..ecbdb21b7 100644 --- a/.idea/runConfigurations/ra6m5.xml +++ b/.idea/runConfigurations/ra6m5.xml @@ -1,5 +1,5 @@ - + diff --git a/.idea/runConfigurations/rp2040.xml b/.idea/runConfigurations/rp2040.xml index 51ae689be..51ab7b5cc 100644 --- a/.idea/runConfigurations/rp2040.xml +++ b/.idea/runConfigurations/rp2040.xml @@ -1,5 +1,5 @@ - + diff --git a/.idea/runConfigurations/rt1010.xml b/.idea/runConfigurations/rt1010.xml index f3c73929d..f415c0676 100644 --- a/.idea/runConfigurations/rt1010.xml +++ b/.idea/runConfigurations/rt1010.xml @@ -1,5 +1,5 @@ - + diff --git a/.idea/runConfigurations/rt1060.xml b/.idea/runConfigurations/rt1060.xml index 191523cbb..cc75aa62c 100644 --- a/.idea/runConfigurations/rt1060.xml +++ b/.idea/runConfigurations/rt1060.xml @@ -1,5 +1,5 @@ - + diff --git a/.idea/runConfigurations/samd21g18.xml b/.idea/runConfigurations/samd21g18.xml index 1baac68f1..f8aa6009d 100644 --- a/.idea/runConfigurations/samd21g18.xml +++ b/.idea/runConfigurations/samd21g18.xml @@ -1,5 +1,5 @@ - + diff --git a/.idea/runConfigurations/samd51j19.xml b/.idea/runConfigurations/samd51j19.xml index 4cf88bad0..694ea7dfd 100644 --- a/.idea/runConfigurations/samd51j19.xml +++ b/.idea/runConfigurations/samd51j19.xml @@ -1,5 +1,5 @@ - + diff --git a/.idea/runConfigurations/stlink.xml b/.idea/runConfigurations/stlink.xml index fa2d8bfca..628f7910d 100644 --- a/.idea/runConfigurations/stlink.xml +++ b/.idea/runConfigurations/stlink.xml @@ -1,5 +1,5 @@ - + diff --git a/.idea/runConfigurations/stm32g474.xml b/.idea/runConfigurations/stm32g474.xml index 928c8fbeb..6d65e83c7 100644 --- a/.idea/runConfigurations/stm32g474.xml +++ b/.idea/runConfigurations/stm32g474.xml @@ -1,5 +1,5 @@ - + diff --git a/.idea/runConfigurations/stm32h743.xml b/.idea/runConfigurations/stm32h743.xml index 1d0c0155d..aeaf9fb53 100644 --- a/.idea/runConfigurations/stm32h743.xml +++ b/.idea/runConfigurations/stm32h743.xml @@ -1,6 +1,6 @@ - - + + diff --git a/.idea/runConfigurations/uno_r4.xml b/.idea/runConfigurations/uno_r4.xml index 7e75e39cd..98bf91812 100644 --- a/.idea/runConfigurations/uno_r4.xml +++ b/.idea/runConfigurations/uno_r4.xml @@ -1,5 +1,5 @@ - + From eaec0fb13998ab642bd63981e8d0686fab0b347c Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 24 Apr 2024 12:12:39 +0700 Subject: [PATCH 362/454] skip clang rp2040 build --- .github/workflows/build_cmake.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml index ee6d83992..1f74bda70 100644 --- a/.github/workflows/build_cmake.yml +++ b/.github/workflows/build_cmake.yml @@ -132,7 +132,7 @@ jobs: #- 'mcx' not working with gcc anymore, need to fix this first - 'nrf' #- 'ra' port later - - 'rp2040' + #- 'rp2040' port later - 'samd21' - 'samd51' - 'stm32f0' @@ -193,7 +193,7 @@ jobs: PICO_SDK_PATH: ${{ github.workspace }}/pico-sdk # --------------------------------------- - # Build ARM with Clang + # Build MSP430 with GCC # --------------------------------------- msp430-gcc: runs-on: ubuntu-latest From b67cb26e51c7f31db0cf71c6c1ce5430bbbbb7f5 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 24 Apr 2024 16:17:33 +0700 Subject: [PATCH 363/454] change hil board s3 devkitm (devkitc seems to have usb issue with cp2104) --- .github/workflows/build_aarch64.yml | 2 +- .github/workflows/build_cmake.yml | 4 +- .github/workflows/build_esp.yml | 6 +- .github/workflows/build_renesas.yml | 2 +- .github/workflows/build_riscv.yml | 2 +- examples/build_system/make/make.mk | 60 +++++++++---------- .../build_system/make/toolchain/arm_gcc.mk | 3 + .../build_system/make/toolchain/arm_iar.mk | 2 + examples/device/cdc_msc_freertos/Makefile | 2 +- .../device/hid_composite_freertos/Makefile | 2 +- examples/host/cdc_msc_hid_freertos/Makefile | 2 +- hw/bsp/board.c | 13 ++-- hw/bsp/board_api.h | 1 + test/hil/hil_pi4.json | 6 +- 14 files changed, 56 insertions(+), 51 deletions(-) diff --git a/.github/workflows/build_aarch64.yml b/.github/workflows/build_aarch64.yml index e5dbf9494..237692498 100644 --- a/.github/workflows/build_aarch64.yml +++ b/.github/workflows/build_aarch64.yml @@ -47,7 +47,7 @@ jobs: 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@v3 + uses: actions/cache@v4 id: cache-toolchain with: path: ~/cache/ diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml index 1f74bda70..65de47e8d 100644 --- a/.github/workflows/build_cmake.yml +++ b/.github/workflows/build_cmake.yml @@ -168,7 +168,7 @@ jobs: 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@v3 + uses: actions/cache@v4 id: cache-toolchain with: path: ~/cache/ @@ -216,7 +216,7 @@ jobs: 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@v3 + uses: actions/cache@v4 id: cache-toolchain with: path: ~/cache/ diff --git a/.github/workflows/build_esp.yml b/.github/workflows/build_esp.yml index d283c6535..4108a58a5 100644 --- a/.github/workflows/build_esp.yml +++ b/.github/workflows/build_esp.yml @@ -34,7 +34,7 @@ jobs: # ESP32-S2 - 'espressif_kaluga_1' # ESP32-S3 - - 'espressif_s3_devkitc' + - 'espressif_s3_devkitm' steps: - name: Setup Python uses: actions/setup-python@v5 @@ -51,7 +51,7 @@ jobs: run: docker run --rm -v $PWD:/project -w /project espressif/idf:v5.1.1 python3 tools/build_esp32.py ${{ matrix.board }} - name: Upload Artifacts for Hardware Testing - if: matrix.board == 'espressif_s3_devkitc' && github.repository_owner == 'hathach' + if: matrix.board == 'espressif_s3_devkitm' && github.repository_owner == 'hathach' uses: actions/upload-artifact@v4 with: name: ${{ matrix.board }} @@ -75,7 +75,7 @@ jobs: fail-fast: false matrix: board: - - 'espressif_s3_devkitc' + - 'espressif_s3_devkitm' steps: - name: Clean workspace run: | diff --git a/.github/workflows/build_renesas.yml b/.github/workflows/build_renesas.yml index ec06c9426..fbc12d285 100644 --- a/.github/workflows/build_renesas.yml +++ b/.github/workflows/build_renesas.yml @@ -46,7 +46,7 @@ jobs: 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@v3 + uses: actions/cache@v4 id: cache-toolchain with: path: ~/cache/ diff --git a/.github/workflows/build_riscv.yml b/.github/workflows/build_riscv.yml index e891a3a51..7f5031ff1 100644 --- a/.github/workflows/build_riscv.yml +++ b/.github/workflows/build_riscv.yml @@ -48,7 +48,7 @@ jobs: 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@v3 + uses: actions/cache@v4 id: cache-toolchain with: path: ~/cache/ diff --git a/examples/build_system/make/make.mk b/examples/build_system/make/make.mk index 772befca4..2437b8766 100644 --- a/examples/build_system/make/make.mk +++ b/examples/build_system/make/make.mk @@ -15,6 +15,8 @@ TOP = $(abspath $(subst make.mk,../../..,$(THIS_MAKEFILE))) # Set CURRENT_PATH to the relative path from TOP to the current directory, ie examples/device/cdc_msc_freertos CURRENT_PATH = $(subst $(TOP)/,,$(abspath .)) +#-------------- Linux/Windows ------------ + # Detect whether shell style is windows or not # https://stackoverflow.com/questions/714100/os-detecting-makefile/52062069#52062069 ifeq '$(findstring ;,$(PATH))' ';' @@ -26,13 +28,18 @@ CMDEXE := 1 SHELL := cmd.exe endif -# Handy check parameter function -check_defined = \ - $(strip $(foreach 1,$1, \ - $(call __check_defined,$1,$(strip $(value 2))))) -__check_defined = \ - $(if $(value $1),, \ - $(error Undefined make flag: $1$(if $2, ($2)))) +ifeq ($(CMDEXE),1) + CP = copy + RM = del + MKDIR = mkdir + PYTHON = python +else + CP = cp + RM = rm + MKDIR = mkdir + PYTHON = python3 +endif + # Build directory BUILD := _build/$(BOARD) @@ -44,8 +51,8 @@ BIN := $(TOP)/_bin/$(BOARD)/$(notdir $(CURDIR)) # Board without family ifneq ($(wildcard $(TOP)/hw/bsp/$(BOARD)/board.mk),) -BOARD_PATH := hw/bsp/$(BOARD) -FAMILY := + BOARD_PATH := hw/bsp/$(BOARD) + FAMILY := endif # Board within family @@ -68,31 +75,12 @@ else SRC_C += $(subst $(TOP)/,,$(wildcard $(TOP)/$(FAMILY_PATH)/*.c)) endif -#-------------- Toolchain ------------ - -# Supported toolchain: gcc, iar +#------------------------------------------------------------- +# Toolchain +# Can be changed via TOOLCHAIN=gcc|iar or CC=arm-none-eabi-gcc|iccarm|clang +#------------------------------------------------------------- TOOLCHAIN ?= gcc -# Can be set by board, default to ARM GCC -CROSS_COMPILE ?= arm-none-eabi- - -ifeq ($(TOOLCHAIN),iar) -CC := iccarm -USE_IAR = 1 -endif - -ifeq ($(CMDEXE),1) - CP = copy - RM = del - MKDIR = mkdir - PYTHON = python -else - CP = cp - RM = rm - MKDIR = mkdir - PYTHON = python3 -endif - #-------------- Source files and compiler flags -------------- # tinyusb makefile include $(TOP)/src/tinyusb.mk @@ -143,3 +131,11 @@ endif # toolchain specific include ${TOP}/examples/build_system/make/toolchain/arm_$(TOOLCHAIN).mk + +# Handy check parameter function +check_defined = \ + $(strip $(foreach 1,$1, \ + $(call __check_defined,$1,$(strip $(value 2))))) +__check_defined = \ + $(if $(value $1),, \ + $(error Undefined make flag: $1$(if $2, ($2)))) diff --git a/examples/build_system/make/toolchain/arm_gcc.mk b/examples/build_system/make/toolchain/arm_gcc.mk index ed5ddc970..c34581ae2 100644 --- a/examples/build_system/make/toolchain/arm_gcc.mk +++ b/examples/build_system/make/toolchain/arm_gcc.mk @@ -1,5 +1,8 @@ # makefile for arm gcc toolchain +# Can be set by family, default to ARM GCC +CROSS_COMPILE ?= arm-none-eabi- + CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ AS = $(CC) -x assembler-with-cpp diff --git a/examples/build_system/make/toolchain/arm_iar.mk b/examples/build_system/make/toolchain/arm_iar.mk index 04c9f22b3..17967b41a 100644 --- a/examples/build_system/make/toolchain/arm_iar.mk +++ b/examples/build_system/make/toolchain/arm_iar.mk @@ -1,4 +1,6 @@ # makefile for arm iar toolchain + +CC = iccarm AS = iasmarm LD = ilinkarm OBJCOPY = ielftool --silent diff --git a/examples/device/cdc_msc_freertos/Makefile b/examples/device/cdc_msc_freertos/Makefile index 13f336f99..fe3fb6482 100644 --- a/examples/device/cdc_msc_freertos/Makefile +++ b/examples/device/cdc_msc_freertos/Makefile @@ -1,7 +1,7 @@ include ../../build_system/make/make.mk FREERTOS_SRC = lib/FreeRTOS-Kernel -FREERTOS_PORTABLE_PATH= $(FREERTOS_SRC)/portable/$(if $(USE_IAR),IAR,GCC) +FREERTOS_PORTABLE_PATH = $(FREERTOS_SRC)/portable/$(if $(findstring iar,$(TOOLCHAIN)),IAR,GCC) INC += \ src \ diff --git a/examples/device/hid_composite_freertos/Makefile b/examples/device/hid_composite_freertos/Makefile index add9e9814..88d602393 100644 --- a/examples/device/hid_composite_freertos/Makefile +++ b/examples/device/hid_composite_freertos/Makefile @@ -3,7 +3,7 @@ DEPS_SUBMODULES += lib/FreeRTOS-Kernel include ../../build_system/make/make.mk FREERTOS_SRC = lib/FreeRTOS-Kernel -FREERTOS_PORTABLE_PATH= $(FREERTOS_SRC)/portable/$(if $(USE_IAR),IAR,GCC) +FREERTOS_PORTABLE_PATH= $(FREERTOS_SRC)/portable/$(if $(findstring iar,$(TOOLCHAIN)),IAR,GCC) INC += \ src \ diff --git a/examples/host/cdc_msc_hid_freertos/Makefile b/examples/host/cdc_msc_hid_freertos/Makefile index 5351a6248..bf4725f47 100644 --- a/examples/host/cdc_msc_hid_freertos/Makefile +++ b/examples/host/cdc_msc_hid_freertos/Makefile @@ -1,7 +1,7 @@ include ../../build_system/make/make.mk FREERTOS_SRC = lib/FreeRTOS-Kernel -FREERTOS_PORTABLE_PATH= $(FREERTOS_SRC)/portable/$(if $(USE_IAR),IAR,GCC) +FREERTOS_PORTABLE_PATH= $(FREERTOS_SRC)/portable/$(if $(findstring iar,$(TOOLCHAIN)),IAR,GCC) INC += \ src \ diff --git a/hw/bsp/board.c b/hw/bsp/board.c index 996ac9263..cdef5e1e5 100644 --- a/hw/bsp/board.c +++ b/hw/bsp/board.c @@ -25,6 +25,14 @@ #include "board_api.h" +//--------------------------------------------------------------------+ +// Board API +//--------------------------------------------------------------------+ +int board_getchar(void) { + char c; + return (sys_read(0, &c, 1) > 0) ? (int) c : (-1); +} + //--------------------------------------------------------------------+ // newlib read()/write() retarget //--------------------------------------------------------------------+ @@ -126,8 +134,3 @@ FILE *const stdin = &__stdio; __strong_reference(stdin, stdout); __strong_reference(stdin, stderr); #endif - -int board_getchar(void) { - char c; - return (sys_read(0, &c, 1) > 0) ? (int) c : (-1); -} diff --git a/hw/bsp/board_api.h b/hw/bsp/board_api.h index 418ce3551..f21a32371 100644 --- a/hw/bsp/board_api.h +++ b/hw/bsp/board_api.h @@ -142,6 +142,7 @@ static inline size_t board_usb_get_serial(uint16_t desc_str1[], size_t max_chars uint8_t uid[16] TU_ATTR_ALIGNED(4); size_t uid_len; + // TODO work with make, but not working with esp32s3 cmake if ( board_get_unique_id ) { uid_len = board_get_unique_id(uid, sizeof(uid)); }else { diff --git a/test/hil/hil_pi4.json b/test/hil/hil_pi4.json index 17d9ff1fa..8aff81910 100644 --- a/test/hil/hil_pi4.json +++ b/test/hil/hil_pi4.json @@ -8,13 +8,13 @@ "flasher_args": "-f interface/cmsis-dap.cfg -f target/rp2040.cfg -c \"adapter speed 5000\"" }, { - "name": "espressif_s3_devkitc", - "uid": "7CDFA1E073CC", + "name": "espressif_s3_devkitm", + "uid": "84F703C084E4", "tests": [ "cdc_msc_freertos", "hid_composite_freertos" ], "flasher": "esptool", - "flasher_sn": "461cb8d7decdeb119be9b506e93fd3f1", + "flasher_sn": "3ea619acd1cdeb11a0a0b806e93fd3f1", "flasher_args": "-b 1500000" }, { From 366f1cf1863bad626af10347f8ff3d0ef7f6ea2b Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Wed, 24 Apr 2024 16:32:56 +0700 Subject: [PATCH 364/454] Fix bsp mistake --- hw/bsp/board.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/hw/bsp/board.c b/hw/bsp/board.c index cdef5e1e5..bb339f613 100644 --- a/hw/bsp/board.c +++ b/hw/bsp/board.c @@ -25,14 +25,6 @@ #include "board_api.h" -//--------------------------------------------------------------------+ -// Board API -//--------------------------------------------------------------------+ -int board_getchar(void) { - char c; - return (sys_read(0, &c, 1) > 0) ? (int) c : (-1); -} - //--------------------------------------------------------------------+ // newlib read()/write() retarget //--------------------------------------------------------------------+ @@ -134,3 +126,11 @@ FILE *const stdin = &__stdio; __strong_reference(stdin, stdout); __strong_reference(stdin, stderr); #endif + +//--------------------------------------------------------------------+ +// Board API +//--------------------------------------------------------------------+ +int board_getchar(void) { + char c; + return (sys_read(0, &c, 1) > 0) ? (int) c : (-1); +} From a7bf0e3e7f7799c28e370826710810033c117744 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 24 Apr 2024 19:21:26 +0700 Subject: [PATCH 365/454] clang make work for samd21 --- examples/build_system/make/cpu/cortex-m0.mk | 8 +++ .../build_system/make/cpu/cortex-m0plus.mk | 8 +++ examples/build_system/make/cpu/cortex-m23.mk | 8 +++ examples/build_system/make/cpu/cortex-m3.mk | 13 ++-- .../make/cpu/cortex-m33-nodsp-nofp.mk | 14 +++- examples/build_system/make/cpu/cortex-m33.mk | 12 +++- examples/build_system/make/cpu/cortex-m4.mk | 9 +++ examples/build_system/make/cpu/cortex-m7.mk | 8 +++ examples/build_system/make/cpu/msp430.mk | 4 ++ examples/build_system/make/make.mk | 28 ++++++-- examples/build_system/make/rules.mk | 2 +- .../build_system/make/toolchain/arm_clang.mk | 10 +++ .../build_system/make/toolchain/arm_gcc.mk | 68 +----------------- .../make/toolchain/clang_rules.mk | 1 + .../build_system/make/toolchain/gcc_common.mk | 71 +++++++++++++++++++ .../{arm_gcc_rules.mk => gcc_rules.mk} | 9 +-- .../{arm_iar_rules.mk => iar_rules.mk} | 0 hw/bsp/samd21/family.mk | 7 +- 18 files changed, 191 insertions(+), 89 deletions(-) create mode 100644 examples/build_system/make/toolchain/arm_clang.mk create mode 100644 examples/build_system/make/toolchain/clang_rules.mk create mode 100644 examples/build_system/make/toolchain/gcc_common.mk rename examples/build_system/make/toolchain/{arm_gcc_rules.mk => gcc_rules.mk} (92%) rename examples/build_system/make/toolchain/{arm_iar_rules.mk => iar_rules.mk} (100%) diff --git a/examples/build_system/make/cpu/cortex-m0.mk b/examples/build_system/make/cpu/cortex-m0.mk index feb0f395b..c2c33a2ee 100644 --- a/examples/build_system/make/cpu/cortex-m0.mk +++ b/examples/build_system/make/cpu/cortex-m0.mk @@ -4,10 +4,18 @@ ifeq ($(TOOLCHAIN),gcc) -mcpu=cortex-m0 \ -mfloat-abi=soft \ +else ifeq ($(TOOLCHAIN),clang) + CFLAGS += \ + --target=arm-none-eabi \ + -mcpu=cortex-m0 \ + else ifeq ($(TOOLCHAIN),iar) # IAR Flags CFLAGS += --cpu cortex-m0 ASFLAGS += --cpu cortex-m0 + +else + $(error "TOOLCHAIN is not supported") endif # For freeRTOS port source diff --git a/examples/build_system/make/cpu/cortex-m0plus.mk b/examples/build_system/make/cpu/cortex-m0plus.mk index b416b7a4a..fe8feb227 100644 --- a/examples/build_system/make/cpu/cortex-m0plus.mk +++ b/examples/build_system/make/cpu/cortex-m0plus.mk @@ -4,10 +4,18 @@ ifeq ($(TOOLCHAIN),gcc) -mcpu=cortex-m0plus \ -mfloat-abi=soft \ +else ifeq ($(TOOLCHAIN),clang) + CFLAGS += \ + --target=arm-none-eabi \ + -mcpu=cortex-m0plus \ + else ifeq ($(TOOLCHAIN),iar) # IAR Flags CFLAGS += --cpu cortex-m0+ ASFLAGS += --cpu cortex-m0+ + +else + $(error "TOOLCHAIN is not supported") endif # For freeRTOS port source diff --git a/examples/build_system/make/cpu/cortex-m23.mk b/examples/build_system/make/cpu/cortex-m23.mk index 29542d8e8..7ab758352 100644 --- a/examples/build_system/make/cpu/cortex-m23.mk +++ b/examples/build_system/make/cpu/cortex-m23.mk @@ -4,10 +4,18 @@ ifeq ($(TOOLCHAIN),gcc) -mcpu=cortex-m23 \ -mfloat-abi=soft \ +else ifeq ($(TOOLCHAIN),clang) + CFLAGS += \ + --target=arm-none-eabi \ + -mcpu=cortex-m23 \ + else ifeq ($(TOOLCHAIN),iar) # IAR Flags CFLAGS += --cpu cortex-m23 ASFLAGS += --cpu cortex-m23 + +else + $(error "TOOLCHAIN is not supported") endif # For freeRTOS port source diff --git a/examples/build_system/make/cpu/cortex-m3.mk b/examples/build_system/make/cpu/cortex-m3.mk index 7a34b9e04..b6325313f 100644 --- a/examples/build_system/make/cpu/cortex-m3.mk +++ b/examples/build_system/make/cpu/cortex-m3.mk @@ -4,13 +4,18 @@ ifeq ($(TOOLCHAIN),gcc) -mcpu=cortex-m3 \ -mfloat-abi=soft \ +else ifeq ($(TOOLCHAIN),clang) + CFLAGS += \ + --target=arm-none-eabi \ + -mcpu=cortex-m3 \ + else ifeq ($(TOOLCHAIN),iar) # IAR Flags - CFLAGS += \ - --cpu cortex-m3 \ + CFLAGS += --cpu cortex-m3 + ASFLAGS += --cpu cortex-m3 - ASFLAGS += \ - --cpu cortex-m3 +else + $(error "TOOLCHAIN is not supported") endif # For freeRTOS port source diff --git a/examples/build_system/make/cpu/cortex-m33-nodsp-nofp.mk b/examples/build_system/make/cpu/cortex-m33-nodsp-nofp.mk index c65f24376..405053dd0 100644 --- a/examples/build_system/make/cpu/cortex-m33-nodsp-nofp.mk +++ b/examples/build_system/make/cpu/cortex-m33-nodsp-nofp.mk @@ -1,16 +1,24 @@ ifeq ($(TOOLCHAIN),gcc) - CFLAGS += \ + CFLAGS += \ -mthumb \ -mcpu=cortex-m33+nodsp \ -mfloat-abi=soft \ +else ifeq ($(TOOLCHAIN),clang) + CFLAGS += \ + --target=arm-none-eabi \ + -mcpu=cortex-m33 \ + -mfpu=softvp \ + else ifeq ($(TOOLCHAIN),iar) - CFLAGS += \ + CFLAGS += \ --cpu cortex-m33+nodsp \ - ASFLAGS += \ + ASFLAGS += \ --cpu cortex-m33+nodsp \ +else + $(error "TOOLCHAIN is not supported") endif FREERTOS_PORTABLE_SRC ?= $(FREERTOS_PORTABLE_PATH)/ARM_CM33_NTZ/non_secure diff --git a/examples/build_system/make/cpu/cortex-m33.mk b/examples/build_system/make/cpu/cortex-m33.mk index fe5b7b380..47b0eaecd 100644 --- a/examples/build_system/make/cpu/cortex-m33.mk +++ b/examples/build_system/make/cpu/cortex-m33.mk @@ -5,15 +5,23 @@ ifeq ($(TOOLCHAIN),gcc) -mfloat-abi=hard \ -mfpu=fpv5-sp-d16 \ +else ifeq ($(TOOLCHAIN),clang) + CFLAGS += \ + --target=arm-none-eabi \ + -mcpu=cortex-m33 \ + -mfpu=fpv5-sp-d16 \ + else ifeq ($(TOOLCHAIN),iar) - CFLAGS += \ + CFLAGS += \ --cpu cortex-m33 \ --fpu VFPv5-SP \ - ASFLAGS += \ + ASFLAGS += \ --cpu cortex-m33 \ --fpu VFPv5-SP \ +else + $(error "TOOLCHAIN is not supported") endif FREERTOS_PORTABLE_SRC ?= $(FREERTOS_PORTABLE_PATH)/ARM_CM33_NTZ/non_secure diff --git a/examples/build_system/make/cpu/cortex-m4.mk b/examples/build_system/make/cpu/cortex-m4.mk index d8776b5d8..4e16819d1 100644 --- a/examples/build_system/make/cpu/cortex-m4.mk +++ b/examples/build_system/make/cpu/cortex-m4.mk @@ -5,9 +5,18 @@ ifeq ($(TOOLCHAIN),gcc) -mfloat-abi=hard \ -mfpu=fpv4-sp-d16 \ +else ifeq ($(TOOLCHAIN),clang) + CFLAGS += \ + --target=arm-none-eabi \ + -mcpu=cortex-m4 \ + -mfpu=fpv4-sp-d16 \ + else ifeq ($(TOOLCHAIN),iar) CFLAGS += --cpu cortex-m4 --fpu VFPv4 ASFLAGS += --cpu cortex-m4 --fpu VFPv4 + +else + $(error "TOOLCHAIN is not supported") endif FREERTOS_PORTABLE_SRC ?= $(FREERTOS_PORTABLE_PATH)/ARM_CM4F diff --git a/examples/build_system/make/cpu/cortex-m7.mk b/examples/build_system/make/cpu/cortex-m7.mk index 0e3461787..3e6116179 100644 --- a/examples/build_system/make/cpu/cortex-m7.mk +++ b/examples/build_system/make/cpu/cortex-m7.mk @@ -5,6 +5,12 @@ ifeq ($(TOOLCHAIN),gcc) -mfloat-abi=hard \ -mfpu=fpv5-d16 \ +else ifeq ($(TOOLCHAIN),clang) + CFLAGS += \ + --target=arm-none-eabi \ + -mcpu=cortex-m7 \ + -mfpu=fpv5-d16 \ + else ifeq ($(TOOLCHAIN),iar) CFLAGS += \ --cpu cortex-m7 \ @@ -14,6 +20,8 @@ else ifeq ($(TOOLCHAIN),iar) --cpu cortex-m7 \ --fpu VFPv5_D16 \ +else + $(error "TOOLCHAIN is not supported") endif FREERTOS_PORTABLE_SRC ?= $(FREERTOS_PORTABLE_PATH)/ARM_CM7/r0p1 diff --git a/examples/build_system/make/cpu/msp430.mk b/examples/build_system/make/cpu/msp430.mk index 06340d23b..6daa2c38d 100644 --- a/examples/build_system/make/cpu/msp430.mk +++ b/examples/build_system/make/cpu/msp430.mk @@ -1,7 +1,11 @@ ifeq ($(TOOLCHAIN),gcc) # nothing to add +else ifeq ($(TOOLCHAIN),clang) + # nothing to add else ifeq ($(TOOLCHAIN),iar) # nothing to add +else + $(error "TOOLCHAIN is not supported") endif # For freeRTOS port source diff --git a/examples/build_system/make/make.mk b/examples/build_system/make/make.mk index 2437b8766..1ec42cb50 100644 --- a/examples/build_system/make/make.mk +++ b/examples/build_system/make/make.mk @@ -2,6 +2,26 @@ # Common make definition for all examples # --------------------------------------- +#------------------------------------------------------------- +# Toolchain +# Can be changed via TOOLCHAIN=gcc|iar or CC=arm-none-eabi-gcc|iccarm|clang +#------------------------------------------------------------- + +ifneq (,$(findstring clang,$(CC))) + TOOLCHAIN = clang +else ifneq (,$(findstring iccarm,$(CC))) + TOOLCHAIN = iar +else ifneq (,$(findstring gcc,$(CC))) + TOOLCHAIN = gcc +endif + +# Default to GCC +ifndef TOOLCHAIN + TOOLCHAIN = gcc +endif + +$(info TOOLCHAIN: $(TOOLCHAIN)) + #-------------- TOP and CURRENT_PATH ------------ # Set TOP to be the path to get from the current directory (where make was invoked) to the top of the tree. @@ -75,12 +95,6 @@ else SRC_C += $(subst $(TOP)/,,$(wildcard $(TOP)/$(FAMILY_PATH)/*.c)) endif -#------------------------------------------------------------- -# Toolchain -# Can be changed via TOOLCHAIN=gcc|iar or CC=arm-none-eabi-gcc|iccarm|clang -#------------------------------------------------------------- -TOOLCHAIN ?= gcc - #-------------- Source files and compiler flags -------------- # tinyusb makefile include $(TOP)/src/tinyusb.mk @@ -112,7 +126,7 @@ endif # Logger: default is uart, can be set to rtt or swo ifneq ($(LOGGER),) - CMAKE_DEFSYM += -DLOGGER=$(LOGGER) + CMAKE_DEFSYM += -DLOGGER=$(LOGGER) endif ifeq ($(LOGGER),rtt) diff --git a/examples/build_system/make/rules.mk b/examples/build_system/make/rules.mk index 78fce49d2..7b6b339ed 100644 --- a/examples/build_system/make/rules.mk +++ b/examples/build_system/make/rules.mk @@ -24,7 +24,7 @@ vpath %.c . $(TOP) vpath %.s . $(TOP) vpath %.S . $(TOP) -include ${TOP}/examples/build_system/make/toolchain/arm_$(TOOLCHAIN)_rules.mk +include ${TOP}/examples/build_system/make/toolchain/$(TOOLCHAIN)_rules.mk # --------------------------------------- # Compiler Flags diff --git a/examples/build_system/make/toolchain/arm_clang.mk b/examples/build_system/make/toolchain/arm_clang.mk new file mode 100644 index 000000000..97face39c --- /dev/null +++ b/examples/build_system/make/toolchain/arm_clang.mk @@ -0,0 +1,10 @@ +CC = clang +CXX = clang++ +AS = $(CC) -x assembler-with-cpp +LD = $(CC) + +GDB = $(CROSS_COMPILE)gdb +OBJCOPY = llvm-objcopy +SIZE = llvm-size + +include ${TOP}/examples/build_system/make/toolchain/gcc_common.mk diff --git a/examples/build_system/make/toolchain/arm_gcc.mk b/examples/build_system/make/toolchain/arm_gcc.mk index c34581ae2..a8576f8ee 100644 --- a/examples/build_system/make/toolchain/arm_gcc.mk +++ b/examples/build_system/make/toolchain/arm_gcc.mk @@ -12,73 +12,9 @@ GDB = $(CROSS_COMPILE)gdb OBJCOPY = $(CROSS_COMPILE)objcopy SIZE = $(CROSS_COMPILE)size -CC_VERSION := $(shell $(CC) -dumpversion) -CC_VERSION_MAJOR = $(firstword $(subst ., ,$(CC_VERSION))) - -# --------------------------------------- -# Compiler Flags -# --------------------------------------- CFLAGS += \ - -MD \ - -ggdb \ - -fdata-sections \ - -ffunction-sections \ -fsingle-precision-constant \ - -fno-strict-aliasing \ - -Wall \ - -Wextra \ - -Werror \ - -Wfatal-errors \ - -Wdouble-promotion \ - -Wstrict-prototypes \ - -Wstrict-overflow \ - -Werror-implicit-function-declaration \ - -Wfloat-equal \ - -Wundef \ - -Wshadow \ - -Wwrite-strings \ - -Wsign-compare \ - -Wmissing-format-attribute \ - -Wunreachable-code \ - -Wcast-align \ - -Wcast-function-type \ - -Wcast-qual \ - -Wnull-dereference \ - -Wuninitialized \ - -Wunused \ - -Wreturn-type \ - -Wredundant-decls \ -# conversion is too strict for most mcu driver, may be disable sign/int/arith-conversion -# -Wconversion +LIBS += -lgcc -lm -lnosys -# Size Optimization as default -CFLAGS_OPTIMIZED ?= -Os - -# Debugging/Optimization -ifeq ($(DEBUG), 1) - CFLAGS += -O0 - NO_LTO = 1 -else - CFLAGS += $(CFLAGS_OPTIMIZED) -endif - -# --------------------------------------- -# Linker Flags -# --------------------------------------- -LDFLAGS += \ - -Wl,-Map=$@.map \ - -Wl,-cref \ - -Wl,-gc-sections \ - -# renesas rx does not support --print-memory-usage flags -ifneq ($(FAMILY),rx) -LDFLAGS += -Wl,--print-memory-usage -endif - -# from version 12 -ifeq ($(strip $(if $(CMDEXE),\ - $(shell if $(CC_VERSION_MAJOR) geq 12 (echo 1) else (echo 0)),\ - $(shell expr $(CC_VERSION_MAJOR) \>= 12))), 1) -LDFLAGS += -Wl,--no-warn-rwx-segment -endif +include ${TOP}/examples/build_system/make/toolchain/gcc_common.mk diff --git a/examples/build_system/make/toolchain/clang_rules.mk b/examples/build_system/make/toolchain/clang_rules.mk new file mode 100644 index 000000000..341f705b1 --- /dev/null +++ b/examples/build_system/make/toolchain/clang_rules.mk @@ -0,0 +1 @@ +include ${TOP}/examples/build_system/make/toolchain/gcc_rules.mk diff --git a/examples/build_system/make/toolchain/gcc_common.mk b/examples/build_system/make/toolchain/gcc_common.mk new file mode 100644 index 000000000..6986d8bba --- /dev/null +++ b/examples/build_system/make/toolchain/gcc_common.mk @@ -0,0 +1,71 @@ +# --------------------------------------- +# Compiler Flags +# --------------------------------------- +CFLAGS += \ + -MD \ + -ggdb \ + -fdata-sections \ + -ffunction-sections \ + -fno-strict-aliasing \ + -Wall \ + -Wextra \ + -Werror \ + -Wfatal-errors \ + -Wdouble-promotion \ + -Wstrict-prototypes \ + -Wstrict-overflow \ + -Werror-implicit-function-declaration \ + -Wfloat-equal \ + -Wundef \ + -Wshadow \ + -Wwrite-strings \ + -Wsign-compare \ + -Wmissing-format-attribute \ + -Wunreachable-code \ + -Wcast-align \ + -Wcast-function-type \ + -Wcast-qual \ + -Wnull-dereference \ + -Wuninitialized \ + -Wunused \ + -Wreturn-type \ + -Wredundant-decls \ + +# conversion is too strict for most mcu driver, may be disable sign/int/arith-conversion +# -Wconversion + +# Size Optimization as default +CFLAGS_OPTIMIZED ?= -Os + +# Debugging/Optimization +ifeq ($(DEBUG), 1) + CFLAGS += -O0 + NO_LTO = 1 +else + CFLAGS += $(CFLAGS_OPTIMIZED) +endif + +# --------------------------------------- +# Linker Flags +# --------------------------------------- +LDFLAGS += \ + -Wl,-Map=$@.map \ + -Wl,--cref \ + -Wl,-gc-sections \ + +# renesas rx does not support --print-memory-usage flags +ifneq ($(FAMILY),rx) +LDFLAGS += -Wl,--print-memory-usage +endif + +ifeq ($(TOOLCHAIN),gcc) +CC_VERSION := $(shell $(CC) -dumpversion) +CC_VERSION_MAJOR = $(firstword $(subst ., ,$(CC_VERSION))) + +# from version 12 +ifeq ($(strip $(if $(CMDEXE),\ + $(shell if $(CC_VERSION_MAJOR) geq 12 (echo 1) else (echo 0)),\ + $(shell expr $(CC_VERSION_MAJOR) \>= 12))), 1) +LDFLAGS += -Wl,--no-warn-rwx-segment +endif +endif diff --git a/examples/build_system/make/toolchain/arm_gcc_rules.mk b/examples/build_system/make/toolchain/gcc_rules.mk similarity index 92% rename from examples/build_system/make/toolchain/arm_gcc_rules.mk rename to examples/build_system/make/toolchain/gcc_rules.mk index d295879d9..3cd87db64 100644 --- a/examples/build_system/make/toolchain/arm_gcc_rules.mk +++ b/examples/build_system/make/toolchain/gcc_rules.mk @@ -21,8 +21,13 @@ ifneq ($(CFLAGS_SKIP),) CFLAGS := $(filter-out $(CFLAGS_SKIP),$(CFLAGS)) endif +ifeq ($(TOOLCHAIN),clang) +LDFLAGS += $(CFLAGS) $(LDFLAGS_CLANG) +else LDFLAGS += $(CFLAGS) $(LDFLAGS_GCC) +endif +# TODO should be removed after all examples are updated ifdef LD_FILE LDFLAGS += -Wl,-T,$(TOP)/$(LD_FILE) endif @@ -33,11 +38,7 @@ endif ASFLAGS += $(CFLAGS) -LIBS_GCC ?= -lgcc -lm -lnosys - # libc -LIBS += $(LIBS_GCC) - ifneq ($(BOARD), spresense) LIBS += -lc endif diff --git a/examples/build_system/make/toolchain/arm_iar_rules.mk b/examples/build_system/make/toolchain/iar_rules.mk similarity index 100% rename from examples/build_system/make/toolchain/arm_iar_rules.mk rename to examples/build_system/make/toolchain/iar_rules.mk diff --git a/hw/bsp/samd21/family.mk b/hw/bsp/samd21/family.mk index 3302aade5..309df58fe 100644 --- a/hw/bsp/samd21/family.mk +++ b/hw/bsp/samd21/family.mk @@ -6,7 +6,6 @@ CPU_CORE ?= cortex-m0plus CFLAGS += \ -flto \ - -nostdlib -nostartfiles \ -DCONF_DFLL_OVERWRITE_CALIBRATION=0 \ -DCFG_TUSB_MCU=OPT_MCU_SAMD21 @@ -16,7 +15,11 @@ 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 \ + +LDFLAGS_CLANG += SRC_C += \ src/portable/microchip/samd/dcd_samd.c \ 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: [PATCH 366/454] 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" From eab42d90d42234997ea55c01b1a510c9bb6434aa Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 24 Apr 2024 22:11:08 +0700 Subject: [PATCH 367/454] update clang make build for stm32: f0 f1 f2 f3 f4 f7 h7 g0 g4 l0 l4 samd21 samd51 nrf --- .../build_system/make/toolchain/gcc_rules.mk | 1 + hw/bsp/nrf/family.mk | 21 ++++++++++++------- hw/bsp/samd21/family.mk | 2 +- hw/bsp/samd51/family.mk | 7 ++++--- hw/bsp/stm32f0/family.mk | 5 +++-- hw/bsp/stm32f1/family.mk | 5 +++-- hw/bsp/stm32f2/family.mk | 5 +++-- hw/bsp/stm32f3/family.mk | 5 +++-- hw/bsp/stm32f4/family.mk | 5 +++-- hw/bsp/stm32f7/family.mk | 5 +++-- hw/bsp/stm32g0/family.mk | 5 +++-- hw/bsp/stm32g4/family.mk | 5 +++-- hw/bsp/stm32h5/family.mk | 10 ++++++--- hw/bsp/stm32h7/family.mk | 9 +++++--- hw/bsp/stm32l0/family.mk | 15 +++++++++---- hw/bsp/stm32l4/family.mk | 11 ++++++---- hw/bsp/stm32u5/boards/stm32u575eval/board.mk | 2 +- .../stm32u5/boards/stm32u575nucleo/board.mk | 2 +- hw/bsp/stm32u5/family.mk | 17 +++++++++++---- tools/build_make.py | 10 ++++----- 20 files changed, 95 insertions(+), 52 deletions(-) diff --git a/examples/build_system/make/toolchain/gcc_rules.mk b/examples/build_system/make/toolchain/gcc_rules.mk index 3cd87db64..fc5225503 100644 --- a/examples/build_system/make/toolchain/gcc_rules.mk +++ b/examples/build_system/make/toolchain/gcc_rules.mk @@ -22,6 +22,7 @@ CFLAGS := $(filter-out $(CFLAGS_SKIP),$(CFLAGS)) endif ifeq ($(TOOLCHAIN),clang) +CFLAGS += $(CFLAGS_CLANG) LDFLAGS += $(CFLAGS) $(LDFLAGS_CLANG) else LDFLAGS += $(CFLAGS) $(LDFLAGS_GCC) diff --git a/hw/bsp/nrf/family.mk b/hw/bsp/nrf/family.mk index 29802dc37..b3c05e6db 100644 --- a/hw/bsp/nrf/family.mk +++ b/hw/bsp/nrf/family.mk @@ -8,25 +8,31 @@ include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m4 CFLAGS += \ - -flto \ -DCFG_TUSB_MCU=OPT_MCU_NRF5X \ - -DCONFIG_GPIO_AS_PINRESET + -DCONFIG_GPIO_AS_PINRESET \ + -D__STARTUP_CLEAR_BSS #CFLAGS += -nostdlib #CFLAGS += -D__START=main # suppress warning caused by vendor mcu driver -CFLAGS += \ +CFLAGS_GCC += \ + -flto \ -Wno-error=undef \ -Wno-error=unused-parameter \ + -Wno-error=unused-variable \ -Wno-error=cast-align \ -Wno-error=cast-qual \ - -Wno-error=redundant-decls + -Wno-error=redundant-decls \ -LDFLAGS += \ - -specs=nosys.specs -specs=nano.specs \ +LDFLAGS_GCC += \ + -nostartfiles \ + --specs=nosys.specs --specs=nano.specs \ -L$(TOP)/${NRFX_DIR}/mdk +LDFLAGS_CLANG += \ + -L$(TOP)/${NRFX_DIR}/mdk \ + SRC_C += \ src/portable/nordic/nrf5x/dcd_nrf5x.c \ ${NRFX_DIR}/helpers/nrfx_flag32_allocator.c \ @@ -34,7 +40,8 @@ SRC_C += \ ${NRFX_DIR}/drivers/src/nrfx_power.c \ ${NRFX_DIR}/drivers/src/nrfx_spim.c \ ${NRFX_DIR}/drivers/src/nrfx_uarte.c \ - ${NRFX_DIR}/mdk/system_$(MCU_VARIANT).c + ${NRFX_DIR}/mdk/system_$(MCU_VARIANT).c \ + ${NRFX_DIR}/soc/nrfx_atomic.c INC += \ $(TOP)/$(BOARD_PATH) \ diff --git a/hw/bsp/samd21/family.mk b/hw/bsp/samd21/family.mk index 309df58fe..aabcff4a2 100644 --- a/hw/bsp/samd21/family.mk +++ b/hw/bsp/samd21/family.mk @@ -17,7 +17,7 @@ CFLAGS_SKIP += -Wcast-qual LDFLAGS_GCC += \ -nostdlib -nostartfiles \ - -specs=nosys.specs -specs=nano.specs \ + --specs=nosys.specs --specs=nano.specs \ LDFLAGS_CLANG += diff --git a/hw/bsp/samd51/family.mk b/hw/bsp/samd51/family.mk index 94ca68705..7b90efad0 100644 --- a/hw/bsp/samd51/family.mk +++ b/hw/bsp/samd51/family.mk @@ -6,13 +6,14 @@ CPU_CORE ?= cortex-m4 CFLAGS += \ -flto \ - -nostdlib -nostartfiles \ -DCFG_TUSB_MCU=OPT_MCU_SAMD51 # 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 \ @@ -33,7 +34,7 @@ INC += \ $(TOP)/hw/mcu/microchip/samd51/hal/utils/include \ $(TOP)/hw/mcu/microchip/samd51/hpl/port \ $(TOP)/hw/mcu/microchip/samd51/hri \ - $(TOP)/hw/mcu/microchip/samd51/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/stm32f0/family.mk b/hw/bsp/stm32f0/family.mk index 537df4d7b..431709de0 100644 --- a/hw/bsp/stm32f0/family.mk +++ b/hw/bsp/stm32f0/family.mk @@ -18,12 +18,13 @@ CFLAGS += \ # GCC Flags CFLAGS_GCC += \ -flto \ - -nostdlib -nostartfiles \ # suppress warning caused by vendor mcu driver CFLAGS_GCC += -Wno-error=unused-parameter -Wno-error=cast-align -LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs +LDFLAGS_GCC += \ + -nostdlib -nostartfiles \ + --specs=nosys.specs --specs=nano.specs # ------------------------ # All source paths should be relative to the top level. diff --git a/hw/bsp/stm32f1/family.mk b/hw/bsp/stm32f1/family.mk index 8a5625551..03fbf4010 100644 --- a/hw/bsp/stm32f1/family.mk +++ b/hw/bsp/stm32f1/family.mk @@ -16,12 +16,13 @@ CFLAGS += \ # GCC Flags CFLAGS_GCC += \ -flto \ - -nostdlib -nostartfiles \ # mcu driver cause following warnings CFLAGS_GCC += -Wno-error=cast-align -LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs +LDFLAGS_GCC += \ + -nostdlib -nostartfiles \ + -specs=nosys.specs -specs=nano.specs # ------------------------ # All source paths should be relative to the top level. diff --git a/hw/bsp/stm32f2/family.mk b/hw/bsp/stm32f2/family.mk index c6ef1ec1d..7e71f6eed 100644 --- a/hw/bsp/stm32f2/family.mk +++ b/hw/bsp/stm32f2/family.mk @@ -16,12 +16,13 @@ CFLAGS += \ CFLAGS_GCC += \ -flto \ - -nostdlib -nostartfiles \ # mcu driver cause following warnings CFLAGS_GCC += -Wno-error=sign-compare -LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs +LDFLAGS_GCC += \ + -nostdlib -nostartfiles \ + --specs=nosys.specs --specs=nano.specs SRC_C += \ src/portable/synopsys/dwc2/dcd_dwc2.c \ diff --git a/hw/bsp/stm32f3/family.mk b/hw/bsp/stm32f3/family.mk index be8271d96..4fe3aa99d 100644 --- a/hw/bsp/stm32f3/family.mk +++ b/hw/bsp/stm32f3/family.mk @@ -13,13 +13,14 @@ CPU_CORE ?= cortex-m4 CFLAGS += \ -flto \ - -nostdlib -nostartfiles \ -DCFG_TUSB_MCU=OPT_MCU_STM32F3 # mcu driver cause following warnings CFLAGS += -Wno-error=unused-parameter -LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs +LDFLAGS_GCC += \ + -nostdlib -nostartfiles \ + --specs=nosys.specs --specs=nano.specs SRC_C += \ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \ diff --git a/hw/bsp/stm32f4/family.mk b/hw/bsp/stm32f4/family.mk index ecbbff417..523a1cb04 100644 --- a/hw/bsp/stm32f4/family.mk +++ b/hw/bsp/stm32f4/family.mk @@ -20,12 +20,13 @@ CFLAGS += \ # GCC Flags CFLAGS_GCC += \ -flto \ - -nostdlib -nostartfiles # suppress warning caused by vendor mcu driver CFLAGS_GCC += -Wno-error=cast-align -LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs +LDFLAGS_GCC += \ + -nostdlib -nostartfiles \ + --specs=nosys.specs --specs=nano.specs # ----------------- # Sources & Include diff --git a/hw/bsp/stm32f7/family.mk b/hw/bsp/stm32f7/family.mk index 1cdf23c6b..cc21bd64e 100644 --- a/hw/bsp/stm32f7/family.mk +++ b/hw/bsp/stm32f7/family.mk @@ -30,12 +30,13 @@ endif # GCC Flags CFLAGS_GCC += \ -flto \ - -nostdlib -nostartfiles # mcu driver cause following warnings CFLAGS_GCC += -Wno-error=cast-align -LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs +LDFLAGS_GCC += \ + -nostdlib -nostartfiles \ + --specs=nosys.specs --specs=nano.specs # ----------------- # Sources & Include diff --git a/hw/bsp/stm32g0/family.mk b/hw/bsp/stm32g0/family.mk index fb382b56a..95b8e537d 100644 --- a/hw/bsp/stm32g0/family.mk +++ b/hw/bsp/stm32g0/family.mk @@ -16,12 +16,13 @@ CFLAGS += \ # GCC Flags CFLAGS_GCC += \ -flto \ - -nostdlib -nostartfiles # suppress warning caused by vendor mcu driver CFLAGS_GCC += -Wno-error=cast-align -LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs +LDFLAGS_GCC += \ + -nostdlib -nostartfiles \ + --specs=nosys.specs --specs=nano.specs # ----------------- # Sources & Include diff --git a/hw/bsp/stm32g4/family.mk b/hw/bsp/stm32g4/family.mk index 95cd84dbd..0abd73532 100644 --- a/hw/bsp/stm32g4/family.mk +++ b/hw/bsp/stm32g4/family.mk @@ -15,12 +15,13 @@ CFLAGS += \ # GCC Flags CFLAGS_GCC += \ -flto \ - -nostdlib -nostartfiles \ # suppress warning caused by vendor mcu driver CFLAGS_GCC += -Wno-error=cast-align -LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs +LDFLAGS_GCC += \ + -nostdlib -nostartfiles \ + --specs=nosys.specs --specs=nano.specs # ----------------- # Sources & Include diff --git a/hw/bsp/stm32h5/family.mk b/hw/bsp/stm32h5/family.mk index 270b1c465..792edb2bb 100644 --- a/hw/bsp/stm32h5/family.mk +++ b/hw/bsp/stm32h5/family.mk @@ -16,7 +16,6 @@ CFLAGS += \ # GCC Flags CFLAGS_GCC += \ -flto \ - -nostdlib -nostartfiles \ # suppress warning caused by vendor mcu driver CFLAGS_GCC += \ @@ -24,7 +23,12 @@ CFLAGS_GCC += \ -Wno-error=undef \ -Wno-error=unused-parameter \ -LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs +CFLAGS_CLANG += \ + -Wno-error=parentheses-equality + +LDFLAGS_GCC += \ + -nostdlib -nostartfiles \ + --specs=nosys.specs --specs=nano.specs # ----------------- # Sources & Include @@ -56,7 +60,7 @@ SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_$(MCU_VARIANT).s # Linker LD_FILE_IAR = $(ST_CMSIS)/Source/Templates/iar/linker/$(MCU_VARIANT)_flash.icf -LD_FILE_GCC = $(ST_CMSIS)/Source/Templates/gcc/linker/$(MCU_VARIANT_UPPER)_FLASH.ld +LD_FILE_GCC = $(FAMILY_PATH)/linker/$(MCU_VARIANT_UPPER)_FLASH.ld # flash target using on-board stlink flash: flash-stlink diff --git a/hw/bsp/stm32h7/family.mk b/hw/bsp/stm32h7/family.mk index 0777bb9c2..40df190db 100644 --- a/hw/bsp/stm32h7/family.mk +++ b/hw/bsp/stm32h7/family.mk @@ -30,12 +30,15 @@ endif # GCC Flags CFLAGS_GCC += \ -flto \ - -nostdlib -nostartfiles # suppress warning caused by vendor mcu driver -CFLAGS_GCC += -Wno-error=maybe-uninitialized -Wno-error=cast-align -Wno-error=unused-parameter +CFLAGS_GCC += \ + -Wno-error=cast-align \ + -Wno-error=unused-parameter \ -LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs +LDFLAGS_GCC += \ + -nostdlib -nostartfiles \ + --specs=nosys.specs --specs=nano.specs # ----------------- # Sources & Include diff --git a/hw/bsp/stm32l0/family.mk b/hw/bsp/stm32l0/family.mk index a811e1823..fe7561fc2 100644 --- a/hw/bsp/stm32l0/family.mk +++ b/hw/bsp/stm32l0/family.mk @@ -12,19 +12,26 @@ CPU_CORE ?= cortex-m0plus CFLAGS += \ -flto \ - -nostdlib -nostartfiles \ -DCFG_EXAMPLE_MSC_READONLY \ -DCFG_EXAMPLE_VIDEO_READONLY \ -DCFG_TUSB_MCU=OPT_MCU_STM32L0 # mcu driver cause following warnings -CFLAGS += \ +CFLAGS_GCC += \ -Wno-error=unused-parameter \ -Wno-error=redundant-decls \ -Wno-error=cast-align \ - -Wno-error=maybe-uninitialized -LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs +ifeq ($(TOOLCHAIN),gcc) +CFLAGS_GCC += -Wno-error=maybe-uninitialized +endif + +CFLAGS_CLANG += \ + -Wno-error=parentheses-equality + +LDFLAGS_GCC += \ + -nostdlib -nostartfiles \ + --specs=nosys.specs --specs=nano.specs SRC_C += \ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \ diff --git a/hw/bsp/stm32l4/family.mk b/hw/bsp/stm32l4/family.mk index 956f82263..411436cf6 100644 --- a/hw/bsp/stm32l4/family.mk +++ b/hw/bsp/stm32l4/family.mk @@ -16,12 +16,15 @@ CFLAGS += \ # GCC Flags CFLAGS_GCC += \ -flto \ - -nostdlib -nostartfiles + -Wno-error=cast-align \ -# suppress warning caused by vendor mcu driver -CFLAGS_GCC += -Wno-error=maybe-uninitialized -Wno-error=cast-align +ifeq ($(TOOLCHAIN),gcc) +CFLAGS_GCC += -Wno-error=maybe-uninitialized +endif -LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs +LDFLAGS_GCC += \ + -nostdlib -nostartfiles \ + --specs=nosys.specs --specs=nano.specs # ----------------- # Sources & Include diff --git a/hw/bsp/stm32u5/boards/stm32u575eval/board.mk b/hw/bsp/stm32u5/boards/stm32u575eval/board.mk index 37d59023f..922d67f83 100644 --- a/hw/bsp/stm32u5/boards/stm32u575eval/board.mk +++ b/hw/bsp/stm32u5/boards/stm32u575eval/board.mk @@ -2,7 +2,7 @@ CFLAGS += \ -DSTM32U575xx \ # All source paths should be relative to the top level. -LD_FILE = ${ST_CMSIS}/Source/Templates/gcc/linker/STM32U575xx_FLASH.ld +LD_FILE = ${FAMILY_PATH}/linker/STM32U575xx_FLASH.ld SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32u575xx.s diff --git a/hw/bsp/stm32u5/boards/stm32u575nucleo/board.mk b/hw/bsp/stm32u5/boards/stm32u575nucleo/board.mk index f07157801..1dd157a68 100644 --- a/hw/bsp/stm32u5/boards/stm32u575nucleo/board.mk +++ b/hw/bsp/stm32u5/boards/stm32u575nucleo/board.mk @@ -2,7 +2,7 @@ CFLAGS += \ -DSTM32U575xx \ # All source paths should be relative to the top level. -LD_FILE = ${ST_CMSIS}/Source/Templates/gcc/linker/STM32U575xx_FLASH.ld +LD_FILE = ${FAMILY_PATH}/linker/STM32U575xx_FLASH.ld SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32u575xx.s diff --git a/hw/bsp/stm32u5/family.mk b/hw/bsp/stm32u5/family.mk index 2144ef37b..be5809340 100644 --- a/hw/bsp/stm32u5/family.mk +++ b/hw/bsp/stm32u5/family.mk @@ -8,14 +8,23 @@ include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m33 CFLAGS += \ - -flto \ - -nostdlib -nostartfiles \ -DCFG_TUSB_MCU=OPT_MCU_STM32U5 # suppress warning caused by vendor mcu driver -CFLAGS += -Wno-error=maybe-uninitialized -Wno-error=cast-align -Wno-error=undef -Wno-error=unused-parameter +CFLAGS_GCC += \ + -flto \ + -Wno-error=cast-align \ + -Wno-error=undef \ + -Wno-error=unused-parameter \ + -Wno-error=type-limits \ -LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs +ifeq ($(TOOLCHAIN),gcc) +CFLAGS_GCC += -Wno-error=maybe-uninitialized +endif + +LDFLAGS_GCC += \ + -nostdlib -nostartfiles \ + --specs=nosys.specs --specs=nano.specs SRC_C += \ src/portable/synopsys/dwc2/dcd_dwc2.c \ diff --git a/tools/build_make.py b/tools/build_make.py index f79a452e4..240fc8d64 100644 --- a/tools/build_make.py +++ b/tools/build_make.py @@ -11,7 +11,6 @@ SKIPPED = "\033[33mskipped\033[0m" build_separator = '-' * 106 -make_iar_option = 'TOOLCHAIN=iar' def filter_with_input(mylist): if len(sys.argv) > 1: @@ -36,9 +35,10 @@ def build_family(example, family, make_option): if __name__ == '__main__': - # IAR CC - if make_iar_option not in sys.argv: - make_iar_option = '' + 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 = [] @@ -67,7 +67,7 @@ if __name__ == '__main__': for example in all_examples: print(build_separator) for family in all_families: - fret = build_family(example, family, make_iar_option) + 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))] From 19f1080e381a81d5c56a0494b20c5c06475ffe42 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 24 Apr 2024 22:41:22 +0700 Subject: [PATCH 368/454] fix make build due to clang changes --- examples/build_system/make/make.mk | 2 -- hw/bsp/imxrt/family.mk | 5 ++++- hw/bsp/kinetis_k/family.mk | 3 +++ hw/bsp/kinetis_kl/family.mk | 2 ++ hw/bsp/lpc17/family.mk | 3 ++- hw/bsp/lpc18/family.mk | 5 +++-- hw/bsp/lpc40/family.mk | 3 ++- hw/bsp/lpc43/family.mk | 5 +++-- hw/bsp/lpc54/family.mk | 5 ++++- hw/bsp/lpc55/family.mk | 7 +++++-- 10 files changed, 28 insertions(+), 12 deletions(-) diff --git a/examples/build_system/make/make.mk b/examples/build_system/make/make.mk index 1ec42cb50..a78f4130d 100644 --- a/examples/build_system/make/make.mk +++ b/examples/build_system/make/make.mk @@ -20,8 +20,6 @@ ifndef TOOLCHAIN TOOLCHAIN = gcc endif -$(info TOOLCHAIN: $(TOOLCHAIN)) - #-------------- TOP and CURRENT_PATH ------------ # Set TOP to be the path to get from the current directory (where make was invoked) to the top of the tree. diff --git a/hw/bsp/imxrt/family.mk b/hw/bsp/imxrt/family.mk index c6adcba5a..bde4c4ba6 100644 --- a/hw/bsp/imxrt/family.mk +++ b/hw/bsp/imxrt/family.mk @@ -11,6 +11,7 @@ MCU_DIR = $(SDK_DIR)/devices/$(MCU_VARIANT) CFLAGS += \ -D__ARMVFP__=0 \ -D__ARMFPV5__=0 \ + -D__STARTUP_CLEAR_BSS \ -DXIP_EXTERNAL_FLASH=1 \ -DXIP_BOOT_HEADER_ENABLE=1 \ -DCFG_TUSB_MCU=OPT_MCU_MIMXRT1XXX @@ -26,7 +27,9 @@ endif # mcu driver cause following warnings CFLAGS += -Wno-error=unused-parameter -Wno-error=implicit-fallthrough -Wno-error=redundant-decls -LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs +LDFLAGS_GCC += \ + -nostartfiles \ + --specs=nosys.specs --specs=nano.specs # All source paths should be relative to the top level. LD_FILE ?= $(MCU_DIR)/gcc/$(MCU_VARIANT)xxxxx${MCU_CORE}_flexspi_nor.ld diff --git a/hw/bsp/kinetis_k/family.mk b/hw/bsp/kinetis_k/family.mk index 995873eec..844ce332e 100644 --- a/hw/bsp/kinetis_k/family.mk +++ b/hw/bsp/kinetis_k/family.mk @@ -6,9 +6,12 @@ include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m4 CFLAGS += \ + -D__STARTUP_CLEAR_BSS \ -DCFG_TUSB_MCU=OPT_MCU_KINETIS_K \ LDFLAGS += \ + -nostartfiles \ + --specs=nosys.specs --specs=nano.specs \ -Wl,--defsym,__stack_size__=0x400 \ -Wl,--defsym,__heap_size__=0 diff --git a/hw/bsp/kinetis_kl/family.mk b/hw/bsp/kinetis_kl/family.mk index e331d82b7..1fdce981a 100644 --- a/hw/bsp/kinetis_kl/family.mk +++ b/hw/bsp/kinetis_kl/family.mk @@ -6,9 +6,11 @@ include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m0plus CFLAGS += \ + -D__STARTUP_CLEAR_BSS \ -DCFG_TUSB_MCU=OPT_MCU_KINETIS_KL \ LDFLAGS += \ + -nostartfiles \ -specs=nosys.specs -specs=nano.specs \ -Wl,--defsym,__stack_size__=0x400 \ -Wl,--defsym,__heap_size__=0 diff --git a/hw/bsp/lpc17/family.mk b/hw/bsp/lpc17/family.mk index 694b6cccf..84ed95648 100644 --- a/hw/bsp/lpc17/family.mk +++ b/hw/bsp/lpc17/family.mk @@ -18,7 +18,7 @@ CFLAGS += -Wno-error=strict-prototypes -Wno-error=cast-qual # caused by freeRTOS port !! CFLAGS += -Wno-error=maybe-uninitialized -LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs +LDFLAGS_GCC += --specs=nosys.specs --specs=nano.specs SRC_C += \ src/portable/nxp/lpc17_40/dcd_lpc17_40.c \ @@ -36,3 +36,4 @@ SRC_C += \ INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/$(MCU_DIR)/inc \ + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ diff --git a/hw/bsp/lpc18/family.mk b/hw/bsp/lpc18/family.mk index c36c903ae..f625e926a 100644 --- a/hw/bsp/lpc18/family.mk +++ b/hw/bsp/lpc18/family.mk @@ -14,7 +14,7 @@ CFLAGS += \ # mcu driver cause following warnings CFLAGS += -Wno-error=unused-parameter -Wno-error=strict-prototypes -Wno-error=cast-qual -LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs +LDFLAGS_GCC += --specs=nosys.specs --specs=nano.specs SRC_C += \ src/portable/chipidea/ci_hs/dcd_ci_hs.c \ @@ -30,4 +30,5 @@ SRC_C += \ INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/$(MCU_DIR)/inc \ - $(TOP)/$(MCU_DIR)/inc/config_18xx + $(TOP)/$(MCU_DIR)/inc/config_18xx \ + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ diff --git a/hw/bsp/lpc40/family.mk b/hw/bsp/lpc40/family.mk index fa76789e3..79d868f35 100644 --- a/hw/bsp/lpc40/family.mk +++ b/hw/bsp/lpc40/family.mk @@ -15,7 +15,7 @@ CFLAGS += \ # mcu driver cause following warnings CFLAGS += -Wno-error=strict-prototypes -Wno-error=unused-parameter -Wno-error=cast-qual -LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs +LDFLAGS_GCC += --specs=nosys.specs --specs=nano.specs # All source paths should be relative to the top level. SRC_C += \ @@ -32,4 +32,5 @@ SRC_C += \ INC += \ $(TOP)/$(MCU_DIR)/inc \ + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(BOARD_PATH) diff --git a/hw/bsp/lpc43/family.mk b/hw/bsp/lpc43/family.mk index f24385139..84e7c30b3 100644 --- a/hw/bsp/lpc43/family.mk +++ b/hw/bsp/lpc43/family.mk @@ -18,7 +18,7 @@ CFLAGS += \ -Wno-error=cast-qual \ -Wno-error=incompatible-pointer-types \ -LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs +LDFLAGS_GCC += --specs=nosys.specs --specs=nano.specs SRC_C += \ src/portable/chipidea/ci_hs/dcd_ci_hs.c \ @@ -36,4 +36,5 @@ SRC_C += \ INC += \ $(TOP)/$(BOARD_PATH) \ ${TOP}/${SDK_DIR}/inc \ - ${TOP}/${SDK_DIR}/inc/config_43xx + ${TOP}/${SDK_DIR}/inc/config_43xx \ + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ diff --git a/hw/bsp/lpc54/family.mk b/hw/bsp/lpc54/family.mk index 9b5eac18d..ea4c9c39c 100644 --- a/hw/bsp/lpc54/family.mk +++ b/hw/bsp/lpc54/family.mk @@ -7,6 +7,7 @@ MCU_DIR = $(SDK_DIR)/devices/$(MCU_VARIANT) CFLAGS += \ -flto \ + -D__STARTUP_CLEAR_BSS \ -DCFG_TUSB_MCU=OPT_MCU_LPC54XXX \ -DCFG_TUSB_MEM_ALIGN='__attribute__((aligned(64)))' \ @@ -23,7 +24,9 @@ endif # mcu driver cause following warnings CFLAGS += -Wno-error=unused-parameter -LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs +LDFLAGS_GCC += \ + -nostartfiles \ + --specs=nosys.specs --specs=nano.specs SRC_C += \ src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c \ diff --git a/hw/bsp/lpc55/family.mk b/hw/bsp/lpc55/family.mk index 1b97c43e4..d82e85904 100644 --- a/hw/bsp/lpc55/family.mk +++ b/hw/bsp/lpc55/family.mk @@ -11,9 +11,10 @@ PORT ?= 1 CFLAGS += \ -flto \ + -D__STARTUP_CLEAR_BSS \ -DCFG_TUSB_MCU=OPT_MCU_LPC55XX \ -DCFG_TUSB_MEM_ALIGN='__attribute__((aligned(64)))' \ - -DBOARD_TUD_RHPORT=$(PORT) + -DBOARD_TUD_RHPORT=$(PORT) \ ifeq ($(PORT), 1) $(info "PORT1 High Speed") @@ -28,7 +29,9 @@ endif # mcu driver cause following warnings CFLAGS += -Wno-error=unused-parameter -Wno-error=float-equal -LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs +LDFLAGS_GCC += \ + -nostartfiles \ + --specs=nosys.specs --specs=nano.specs \ # All source paths should be relative to the top level. LD_FILE ?= $(MCU_DIR)/gcc/$(MCU_CORE)_flash.ld From d664cbfcdd1ab34dd82079a7b0a5bec339c37b81 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 25 Apr 2024 11:28:18 +0700 Subject: [PATCH 369/454] fix pre-commit --- lib/rt-thread/SConscript | 2 +- lib/rt-thread/port/msc_device_port.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/rt-thread/SConscript b/lib/rt-thread/SConscript index 14fbf5549..205e12958 100644 --- a/lib/rt-thread/SConscript +++ b/lib/rt-thread/SConscript @@ -36,7 +36,7 @@ if rtconfig.PLATFORM == 'gcc' or rtconfig.PLATFORM == 'armclang': # GCC or Keil LOCAL_CFLAGS += ' -std=c99' elif rtconfig.PLATFORM == 'armcc': # Keil AC5 LOCAL_CFLAGS += ' --c99 --gnu' - + group = DefineGroup('TinyUSB', src, depend = ['PKG_USING_TINYUSB'], CPPPATH = path, LOCAL_CFLAGS = LOCAL_CFLAGS) Return('group') diff --git a/lib/rt-thread/port/msc_device_port.c b/lib/rt-thread/port/msc_device_port.c index 6af3c4f61..c7e8c508e 100644 --- a/lib/rt-thread/port/msc_device_port.c +++ b/lib/rt-thread/port/msc_device_port.c @@ -106,7 +106,7 @@ bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, boo // unload disk storage ejected = true; } - } + } return true; } From 5f473d51cf04a7bfeca71bce09a9b3a4c2b2a7d1 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 18 Apr 2024 20:00:45 +0200 Subject: [PATCH 370/454] Fix IAR breakpoint test. --- src/common/tusb_verify.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/common/tusb_verify.h b/src/common/tusb_verify.h index 8aa66b4df..71406dacf 100644 --- a/src/common/tusb_verify.h +++ b/src/common/tusb_verify.h @@ -76,7 +76,8 @@ #endif // 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__) +#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 \ { \ volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ From 13bde7af403c4f6f3ff6381e23202fc433bffdb2 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Tue, 23 Apr 2024 21:36:05 +0200 Subject: [PATCH 371/454] uac2: return on clear_feature. --- src/class/audio/audio_device.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 9050b462a..9ba38a20c 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -2015,7 +2015,10 @@ static bool audiod_control_request(uint8_t rhport, tusb_control_request_t const case TUSB_REQ_SET_INTERFACE: return audiod_set_interface(rhport, p_request); - // Unknown/Unsupported request + case TUSB_REQ_CLEAR_FEATURE: + return true; + + // Unknown/Unsupported request default: TU_BREAKPOINT(); return false; } } From f32eb074878353dfbb631a932950ea69f81d4b7d Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Tue, 23 Apr 2024 21:38:04 +0200 Subject: [PATCH 372/454] stm32u5: fix IAR build. --- hw/bsp/stm32u5/family.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/bsp/stm32u5/family.c b/hw/bsp/stm32u5/family.c index d7258a717..ec64f7622 100644 --- a/hw/bsp/stm32u5/family.c +++ b/hw/bsp/stm32u5/family.c @@ -249,7 +249,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 From c2f836279e88d15c2dd818f44f3c563071f36bca Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Tue, 23 Apr 2024 21:43:59 +0200 Subject: [PATCH 373/454] Disable EPs correctly to clear incomplete transfer. --- src/portable/synopsys/dwc2/dcd_dwc2.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index c2c09a1fc..692096fc8 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -202,10 +202,10 @@ static void edpt_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoin (xfer->max_size << DOEPCTL_MPSIZ_Pos); if (dir == TUSB_DIR_OUT) { - dwc2->epout[epnum].doepctl |= dxepctl; + dwc2->epout[epnum].doepctl = dxepctl; dwc2->daintmsk |= TU_BIT(DAINTMSK_OEPM_Pos + epnum); } else { - dwc2->epin[epnum].diepctl |= dxepctl | (epnum << DIEPCTL_TXFNUM_Pos); + dwc2->epin[epnum].diepctl = dxepctl | (epnum << DIEPCTL_TXFNUM_Pos); dwc2->daintmsk |= (1 << (DAINTMSK_IEPM_Pos + epnum)); } } @@ -280,10 +280,17 @@ static void bus_reset(uint8_t rhport) { dwc2->epout[n].doepctl |= DOEPCTL_SNAK; } + // 2. Disable all IN endpoints + for (uint8_t n = 0; n < ep_count; n++) { + if (dwc2->epin[n].diepctl & DIEPCTL_EPENA) { + dwc2->epin[n].diepctl |= DIEPCTL_SNAK | DIEPCTL_EPDIS; + } + } + fifo_flush_tx(dwc2, 0x10); // all tx fifo fifo_flush_rx(dwc2); - // 2. Set up interrupt mask + // 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; @@ -704,11 +711,15 @@ void dcd_edpt_close_all(uint8_t rhport) { for (uint8_t n = 1; n < ep_count; n++) { // disable OUT endpoint - dwc2->epout[n].doepctl = 0; + 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 - dwc2->epin[n].diepctl = 0; + if (dwc2->epin[n].diepctl & DIEPCTL_EPENA) { + dwc2->epin[n].diepctl |= DIEPCTL_SNAK | DIEPCTL_EPDIS; + } xfer_status[n][TUSB_DIR_IN].max_size = 0; } 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: [PATCH 374/454] 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 From 2e995d7cf4b2971e3ca7167a097b99832c8d61ce Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 25 Apr 2024 20:23:40 +0700 Subject: [PATCH 375/454] 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 +-- .../device/cdc_msc_freertos/src/tusb_config.h | 2 +- .../device/hid_composite_freertos/src/main.c | 6 +-- .../hid_composite_freertos/src/tusb_config.h | 2 +- examples/device/video_capture/src/main.c | 4 +- .../device/video_capture/src/tusb_config.h | 2 +- examples/device/video_capture_2ch/src/main.c | 4 +- .../video_capture_2ch/src/tusb_config.h | 2 +- .../host/cdc_msc_hid_freertos/src/cdc_app.c | 2 +- examples/host/cdc_msc_hid_freertos/src/main.c | 6 +-- .../cdc_msc_hid_freertos/src/tusb_config.h | 2 +- hw/bsp/board_api.h | 2 +- .../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 From 03ccc8d8dfe21fc158fc5eb8a4f3f90f425f8a3b Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 25 Apr 2024 20:41:44 +0700 Subject: [PATCH 376/454] 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 From 223ce56625474764dc00229c44731858abcf4f29 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 26 Apr 2024 00:10:57 +0700 Subject: [PATCH 377/454] - 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 From 022de87550fdc63dd6dea91f39feecfce59eabe5 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 26 Apr 2024 00:15:04 +0700 Subject: [PATCH 378/454] add devkit c3 board --- .../boards/espressif_c3_devkitc/board.cmake | 2 + .../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_ */ From 7fb8d3341ce2feb46b0bce0bef069d31cf080168 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 26 Apr 2024 13:40:13 +0200 Subject: [PATCH 379/454] 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 From 1661acf82f8e01392de0c18c3472d016679c707d Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 26 Apr 2024 13:42:20 +0200 Subject: [PATCH 380/454] 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]; From 6c3a60e5f2100e3d60bfd4b9b3e28fbab98af1b5 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 26 Apr 2024 14:54:16 +0200 Subject: [PATCH 381/454] 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 From 4af67dd0078009c1378612440afd5806e84a81c7 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 26 Apr 2024 17:45:14 +0200 Subject: [PATCH 382/454] 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 } From 24339dbcce5c5374e0abedf605471753484e4a56 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 26 Apr 2024 18:01:02 +0200 Subject: [PATCH 383/454] 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 += 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++; } + + 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); + 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--; } - 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); - } + 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))); } From 98e85a296deb89dbcc05033bda26e3c9581d535b Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sat, 27 Apr 2024 17:09:05 +0200 Subject: [PATCH 384/454] 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); From fdb431b5c70ff605eebda8988e1728e7118b4ab4 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sat, 27 Apr 2024 17:12:00 +0200 Subject: [PATCH 385/454] 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. From a018b229ba01d146f089e679524dfa72b92ec95a Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sat, 27 Apr 2024 17:12:23 +0200 Subject: [PATCH 386/454] 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 From bd033a2d531d09478ddd947121e12aa6ece86d56 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sat, 27 Apr 2024 17:24:19 +0200 Subject: [PATCH 387/454] 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; } From c917d47e71d9cef3f6cf096cf9606913ef7020fd Mon Sep 17 00:00:00 2001 From: Kasper Nyhus Kaae Date: Mon, 7 Mar 2022 21:30:33 +0100 Subject: [PATCH 388/454] audio_test_freertos & audio_4_channel_mic_freertos --- .../CMakeLists.txt | 22 + .../audio_4_channel_mic_freertos/Makefile | 37 ++ .../audio_4_channel_mic_freertos/README.md | 18 + .../audio_4_channel_mic_freertos/skip.txt | 3 + .../src/CMakeLists.txt | 27 + .../src/FreeRTOSConfig/FreeRTOSConfig.h | 191 +++++++ .../audio_4_channel_mic_freertos/src/main.c | 488 ++++++++++++++++++ .../src/plot_audio_samples.py | 34 ++ .../src/tusb_config.h | 128 +++++ .../src/usb_descriptors.c | 165 ++++++ .../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 + .../audio_test_freertos/src/CMakeLists.txt | 27 + .../src/FreeRTOSConfig/FreeRTOSConfig.h | 191 +++++++ .../device/audio_test_freertos/src/main.c | 486 +++++++++++++++++ .../src/plot_audio_samples.py | 34 ++ .../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: [PATCH 389/454] Update build system. --- .../CMakeLists.txt | 34 ++++-- .../audio_4_channel_mic_freertos/Makefile | 17 +-- .../audio_4_channel_mic_freertos/README.md | 5 +- .../sdkconfig.defaults | 3 + .../audio_4_channel_mic_freertos/skip.txt | 3 +- .../src/CMakeLists.txt | 29 +---- .../src/FreeRTOSConfig/FreeRTOSConfig.h | 45 ++++--- .../src/freertos_hook.c | 115 ++++++++++++++++++ .../audio_4_channel_mic_freertos/src/main.c | 42 +++++-- .../src/tusb_config.h | 45 ++++--- .../device/audio_test_freertos/CMakeLists.txt | 34 ++++-- examples/device/audio_test_freertos/Makefile | 20 +-- examples/device/audio_test_freertos/README.md | 5 +- .../audio_test_freertos/sdkconfig.defaults | 3 + .../audio_test_freertos/src/CMakeLists.txt | 29 +---- .../src/FreeRTOSConfig/FreeRTOSConfig.h | 45 ++++--- .../audio_test_freertos/src/freertos_hook.c | 115 ++++++++++++++++++ .../device/audio_test_freertos/src/main.c | 100 +++++++++------ .../src/plot_audio_samples.py | 2 +- 19 files changed, 481 insertions(+), 210 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" +#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 + #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" +#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 + #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) From 7dd26877de2ed85a608190a76acf960e256c88bf Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sat, 27 Apr 2024 22:16:30 +0200 Subject: [PATCH 390/454] 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 } From bb89a5a5bf0cb13f895675f4480801e52d822203 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sat, 27 Apr 2024 22:17:10 +0200 Subject: [PATCH 391/454] audio_test_freertos : merge changes from audio_test. --- .../device/audio_test_freertos/src/main.c | 12 +-- .../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 +#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 +// 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; - uint8_t chr_count; + switch ( index ) { + case STRID_LANGID: + memcpy(&_desc_str[1], string_desc_arr[0], 2); + chr_count = 1; + break; - if ( index == 0) - { - memcpy(&_desc_str[1], string_desc_arr[0], 2); - chr_count = 1; - }else - { - // Convert ASCII string into UTF-16 + case STRID_SERIAL: + chr_count = board_usb_get_serial(_desc_str + 1, 32); + break; - if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL; + 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 - const char* str = string_desc_arr[index]; + if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) return NULL; - // Cap at max char - chr_count = strlen(str); - if ( chr_count > 31 ) chr_count = 31; + const char *str = string_desc_arr[index]; - for(uint8_t i=0; i 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] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } From a29a3af218e24034af4406eeb7c7f660555d322b Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sun, 28 Apr 2024 00:09:06 +0200 Subject: [PATCH 392/454] audio_4_channel_mic_freertos : merge changes from audio_4_channel_mic. --- .../CMakeLists.txt | 5 + .../sdkconfig.defaults | 1 + .../audio_4_channel_mic_freertos/src/main.c | 150 +++++++++++++----- .../src/tusb_config.h | 41 +++-- .../src/usb_descriptors.c | 76 +++++---- 5 files changed, 190 insertions(+), 83 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 //--------------------------------------------------------------------+ -// 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 +// String Descriptor Index +enum { + STRID_LANGID = 0, + STRID_MANUFACTURER, + STRID_PRODUCT, + STRID_SERIAL, }; -static uint16_t _desc_str[32]; +// 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 + NULL, // 3: Serials will use unique ID if possible + "UAC2", // 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) -{ +uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; + size_t chr_count; - uint8_t chr_count; + switch ( index ) { + case STRID_LANGID: + memcpy(&_desc_str[1], string_desc_arr[0], 2); + chr_count = 1; + break; - if ( index == 0) - { - memcpy(&_desc_str[1], string_desc_arr[0], 2); - chr_count = 1; - }else - { - // Convert ASCII string into UTF-16 + case STRID_SERIAL: + chr_count = board_usb_get_serial(_desc_str + 1, 32); + break; - if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL; + 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 - const char* str = string_desc_arr[index]; + if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) return NULL; - // Cap at max char - chr_count = strlen(str); - if ( chr_count > 31 ) chr_count = 31; + const char *str = string_desc_arr[index]; - for(uint8_t i=0; i 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] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); return _desc_str; } From bc8c8df3163bd41d0220746618f6495425344028 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sun, 28 Apr 2024 00:29:19 +0200 Subject: [PATCH 393/454] Build STM32F7 with single-point FPU. --- .../cmake/cpu/cortex-m7-fpsp.cmake | 25 +++++++++++++++++ .../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 From ef7be4c2ffa0061aec2ea32f530a4037f7309f1e Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sun, 28 Apr 2024 00:40:36 +0200 Subject: [PATCH 394/454] Fix CI. --- examples/device/CMakeLists.txt | 2 ++ .../device/audio_4_channel_mic_freertos/Makefile | 2 +- .../device/audio_4_channel_mic_freertos/skip.txt | 16 +++++++++++++--- .../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 -- .../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. */ From 327e3ec4bd1908e57e2ecd90738f01fc04a17ba1 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sun, 28 Apr 2024 21:59:54 +0200 Subject: [PATCH 395/454] 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 ; From c303b5d81d3dd9d5dc9f831af704e6d40366d7cf Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Mon, 29 Apr 2024 22:35:55 +0200 Subject: [PATCH 396/454] 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 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: [PATCH 397/454] 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); 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: [PATCH 398/454] 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 */\ From ea3f1d39e8bfc82facc7b3e503d7c71f9119de2b Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 2 May 2024 13:29:29 +0700 Subject: [PATCH 399/454] 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 - .../build_system/cmake/cpu/arm1176jzf-s.cmake | 19 ++++ .../make/cpu/{arm1176.mk => arm1176jzf-s.mk} | 0 .../boards/raspberrypi_zero/board.cmake | 8 ++ .../board.h | 0 .../board.mk | 2 +- 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 +- 12 files changed, 155 insertions(+), 20 deletions(-) delete mode 100644 .clang-format create mode 100644 examples/build_system/cmake/cpu/arm1176jzf-s.cmake rename examples/build_system/make/cpu/{arm1176.mk => arm1176jzf-s.mk} (100%) create mode 100644 hw/bsp/broadcom_32bit/boards/raspberrypi_zero/board.cmake rename hw/bsp/broadcom_32bit/boards/{raspberrypi_zero_w => raspberrypi_zero}/board.h (100%) rename hw/bsp/broadcom_32bit/boards/{raspberrypi_zero_w => raspberrypi_zero}/board.mk (77%) 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/arm1176jzf-s.mk similarity index 100% rename from examples/build_system/make/cpu/arm1176.mk rename to examples/build_system/make/cpu/arm1176jzf-s.mk 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_w/board.h b/hw/bsp/broadcom_32bit/boards/raspberrypi_zero/board.h similarity index 100% rename from hw/bsp/broadcom_32bit/boards/raspberrypi_zero_w/board.h rename to hw/bsp/broadcom_32bit/boards/raspberrypi_zero/board.h diff --git a/hw/bsp/broadcom_32bit/boards/raspberrypi_zero_w/board.mk b/hw/bsp/broadcom_32bit/boards/raspberrypi_zero/board.mk similarity index 77% rename from hw/bsp/broadcom_32bit/boards/raspberrypi_zero_w/board.mk rename to hw/bsp/broadcom_32bit/boards/raspberrypi_zero/board.mk index 052033230..7a248ed24 100644 --- a/hw/bsp/broadcom_32bit/boards/raspberrypi_zero_w/board.mk +++ b/hw/bsp/broadcom_32bit/boards/raspberrypi_zero/board.mk @@ -1,4 +1,4 @@ -CPU_CORE = arm1176 +CPU_CORE = arm1176jzf-s CFLAGS += -DBCM_VERSION=2835 \ -DCFG_TUSB_MCU=OPT_MCU_BCM2835 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) From 980f5992c8bc9b66e13cd409ae782a588053ec3e Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 2 May 2024 16:57:50 +0700 Subject: [PATCH 400/454] add cmake for broadcom 64-bit, like 32-bit it compiles but text is only 8 bytes (incorrect) --- .../build_system/cmake/cpu/cortex-a53.cmake | 17 +++ .../build_system/cmake/cpu/cortex-a72.cmake | 17 +++ .../cmake/toolchain/aarch64_gcc.cmake | 21 ++++ .../boards/raspberrypi_cm4/board.cmake | 5 + .../boards/raspberrypi_zero2/board.cmake | 5 + .../board.h | 0 .../board.mk | 0 hw/bsp/broadcom_64bit/family.c | 11 ++ hw/bsp/broadcom_64bit/family.cmake | 110 ++++++++++++++++++ hw/bsp/broadcom_64bit/family.mk | 6 +- 10 files changed, 187 insertions(+), 5 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 rename hw/bsp/broadcom_64bit/boards/{raspberrypi_zero2w => raspberrypi_zero2}/board.h (100%) rename hw/bsp/broadcom_64bit/boards/{raspberrypi_zero2w => raspberrypi_zero2}/board.mk (100%) 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_zero2w/board.h b/hw/bsp/broadcom_64bit/boards/raspberrypi_zero2/board.h similarity index 100% rename from hw/bsp/broadcom_64bit/boards/raspberrypi_zero2w/board.h rename to hw/bsp/broadcom_64bit/boards/raspberrypi_zero2/board.h diff --git a/hw/bsp/broadcom_64bit/boards/raspberrypi_zero2w/board.mk b/hw/bsp/broadcom_64bit/boards/raspberrypi_zero2/board.mk similarity index 100% rename from hw/bsp/broadcom_64bit/boards/raspberrypi_zero2w/board.mk rename to hw/bsp/broadcom_64bit/boards/raspberrypi_zero2/board.mk 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 $^ $@ From 4b537a4f8c96519a3e77a63ff8ddbb3c528bd857 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 2 May 2024 16:58:43 +0700 Subject: [PATCH 401/454] add cmake for kinetis k32l2 family --- .../FreeRTOSConfig/FreeRTOSConfig.h | 169 +++++++++++++++ .../boards/frdm_k32l2a4s/board.cmake | 15 ++ .../boards/frdm_k32l2a4s/board.h | 34 +++ .../boards/frdm_k32l2a4s/clock_config.c | 2 +- .../boards/frdm_k32l2b/board.cmake | 15 ++ .../kinetis_k32l2/boards/frdm_k32l2b/board.h | 22 ++ .../boards/frdm_k32l2b/clock_config.c | 2 +- .../boards/frdm_k32l2b/frdm_k32l2b.c | 140 ------------ 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 +- .../kinetis_k32l2/boards/kuiic/clock_config.c | 39 ++++ .../kinetis_k32l2/boards/kuiic/clock_config.h | 14 ++ hw/bsp/kinetis_k32l2/boards/kuiic/kuiic.c | 203 ------------------ .../{K32L2B31xxxxA_flash.ld => kuiic.ld} | 0 .../frdm_k32l2a4s.c => family.c} | 129 ++++++----- hw/bsp/kinetis_k32l2/family.cmake | 112 ++++++++++ hw/bsp/kinetis_k32l2/family.mk | 9 +- 18 files changed, 527 insertions(+), 415 deletions(-) create mode 100644 hw/bsp/kinetis_k32l2/FreeRTOSConfig/FreeRTOSConfig.h create mode 100644 hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/board.cmake 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 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 rename hw/bsp/kinetis_k32l2/boards/kuiic/{K32L2B31xxxxA_flash.ld => kuiic.ld} (100%) rename hw/bsp/kinetis_k32l2/{boards/frdm_k32l2a4s/frdm_k32l2a4s.c => family.c} (60%) 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/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/K32L2B31xxxxA_flash.ld b/hw/bsp/kinetis_k32l2/boards/kuiic/kuiic.ld similarity index 100% rename from hw/bsp/kinetis_k32l2/boards/kuiic/K32L2B31xxxxA_flash.ld rename to hw/bsp/kinetis_k32l2/boards/kuiic/kuiic.ld diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/frdm_k32l2a4s.c b/hw/bsp/kinetis_k32l2/family.c similarity index 60% rename from hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/frdm_k32l2a4s.c rename to hw/bsp/kinetis_k32l2/family.c index 39783b7e1..92f5ba6d3 100644 --- a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/frdm_k32l2a4s.c +++ b/hw/bsp/kinetis_k32l2/family.c @@ -25,77 +25,57 @@ * 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" +#include "bsp/board_api.h" +#include "board.h" + //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ -void USB0_IRQHandler(void) -{ +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); +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, 0 }; + 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); - gpio_pin_config_t button_config = { kGPIO_DigitalInput, 0 }; +#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_OpenDrainDisable, - kPORT_LowDriveStrength, - kPORT_MuxAsGpio, - kPORT_UnlockRegister + 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); - - /* - Enable LPUART0 clock and configure port pins. - FIR clock is being used so the USB examples work. - */ - PCC_LPUART0 = 0U; /* Clock must be off to set PCS */ - PCC_LPUART0 = PCC_CLKCFG_PCS( 3U ); /* Select the clock. 1:OSCCLK/Bus Clock, 2:Slow IRC, 3: Fast IRC, 6: System PLL */ - PCC_LPUART0 |= PCC_CLKCFG_CGC( 1U ); /* Enable LPUART */ - - /* PORTB16 (pin 62) is configured as LPUART0_RX */ - gpio_pin_config_t const lpuart_config_rx = { kGPIO_DigitalInput, 0 }; - GPIO_PinInit(UART_PIN_GPIO, UART_PIN_RX, &lpuart_config_rx); - const port_pin_config_t UART_CFG = { - kPORT_PullUp, - kPORT_FastSlewRate, - kPORT_PassiveFilterDisable, - kPORT_OpenDrainDisable, - kPORT_LowDriveStrength, - kPORT_MuxAsGpio, - kPORT_UnlockRegister - }; - PORT_SetPinConfig(UART_PIN_PORT, UART_PIN_RX, &UART_CFG); - PORT_SetPinMux( UART_PIN_PORT, UART_PIN_RX, kPORT_MuxAlt3); - - /* PORTB17 (pin 63) is configured as LPUART0_TX */ - gpio_pin_config_t const lpuart_config_tx = { kGPIO_DigitalOutput, 0 }; - GPIO_PinInit( UART_PIN_GPIO, UART_PIN_TX, &lpuart_config_tx); - PORT_SetPinMux( UART_PIN_PORT, UART_PIN_TX, kPORT_MuxAlt3); - - BOARD_BootClockRUN(); - SystemCoreClockUpdate(); +#endif #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer @@ -110,28 +90,29 @@ void board_init(void) 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_ScgFircClk)); + LPUART_Init(UART_PORT, &uart_config, UART_CLOCK_SOURCE_HZ); // USB - CLOCK_EnableUsbfs0Clock(kCLOCK_IpSrcFircAsync, 48000000U); + 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)); +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) -{ +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) -{ +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. @@ -151,21 +132,39 @@ int board_uart_read(uint8_t* buf, int len) #endif } -int board_uart_write(void const * buf, int 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) -{ + +void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) -{ +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 From c717e52ab2453f7672b16f2d63cd70558950ef33 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 2 May 2024 17:54:44 +0700 Subject: [PATCH 402/454] add cmake for lpc11 --- .../audio_4_channel_mic_freertos/skip.txt | 1 + .../FreeRTOSConfig/FreeRTOSConfig.h | 2 +- hw/bsp/lpc11/FreeRTOSConfig/FreeRTOSConfig.h | 178 +++++++++++++++ .../lpc11/boards/lpcxpresso11u37/board.cmake | 19 ++ hw/bsp/lpc11/boards/lpcxpresso11u37/board.h | 98 +++++++++ .../boards/lpcxpresso11u37/lpcxpresso11u37.c | 208 ------------------ .../lpc11/boards/lpcxpresso11u68/board.cmake | 12 + hw/bsp/lpc11/boards/lpcxpresso11u68/board.h | 27 +++ hw/bsp/lpc11/boards/lpcxpresso11u68/board.mk | 1 - .../lpcxpresso11u68.c => family.c} | 75 +++---- hw/bsp/lpc11/family.cmake | 104 +++++++++ hw/bsp/lpc11/family.mk | 5 +- src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c | 10 + 13 files changed, 482 insertions(+), 258 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 rename hw/bsp/lpc11/{boards/lpcxpresso11u68/lpcxpresso11u68.c => family.c} (68%) 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: [PATCH 403/454] 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 From 19cb2f1a3cb7b281101b0465128d4bda23e89d34 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 2 May 2024 18:13:53 +0700 Subject: [PATCH 404/454] add cmake to lpc1347 --- .../audio_4_channel_mic_freertos/skip.txt | 1 + hw/bsp/lpc13/FreeRTOSConfig/FreeRTOSConfig.h | 178 ++++++++++++++++++ .../lpc13/boards/lpcxpresso1347/board.cmake | 11 ++ hw/bsp/lpc13/boards/lpcxpresso1347/board.h | 46 +++++ .../lpcxpresso1347.c => family.c} | 79 ++------ hw/bsp/lpc13/family.cmake | 102 ++++++++++ hw/bsp/lpc13/family.mk | 3 +- 7 files changed, 356 insertions(+), 64 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 rename hw/bsp/lpc13/{boards/lpcxpresso1347/lpcxpresso1347.c => family.c} (55%) 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: [PATCH 405/454] add cmake for lpc15 --- hw/bsp/lpc15/FreeRTOSConfig/FreeRTOSConfig.h | 179 ++++++++++++++++++ .../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: [PATCH 406/454] 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' From 68a4d0c8db0beec4fee22dab003f1e5ec39da310 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 2 May 2024 20:43:27 +0700 Subject: [PATCH 407/454] add cmake to lpc51 --- hw/bsp/lpc51/FreeRTOSConfig/FreeRTOSConfig.h | 169 +++++++++++++++++ .../lpc51/boards/lpcxpresso51u68/board.cmake | 13 ++ hw/bsp/lpc51/boards/lpcxpresso51u68/board.h | 57 ++++++ .../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: [PATCH 408/454] add cmake to msp432e4 --- .github/workflows/build_cmake.yml | 3 +- hw/bsp/msp430/FreeRTOSConfig/FreeRTOSConfig.h | 80 ++++++++++ .../msp432e4/FreeRTOSConfig/FreeRTOSConfig.h | 149 ++++++++++++++++++ .../boards/msp_exp432e401y/board.cmake | 8 + .../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: [PATCH 409/454] add cmake for saml2x --- hw/bsp/samd21/family.cmake | 8 +- hw/bsp/samd21/family.mk | 6 +- .../saml2x/boards/atsaml21_xpro/board.cmake | 9 ++ hw/bsp/saml2x/boards/atsaml21_xpro/board.mk | 4 +- .../boards/atsaml21_xpro/saml21j18b_flash.ld | 2 + .../saml2x/boards/saml22_feather/board.cmake | 9 ++ hw/bsp/saml2x/boards/saml22_feather/board.mk | 4 +- .../boards/saml22_feather/saml22_feather.ld | 4 +- .../saml2x/boards/sensorwatch_m0/board.cmake | 9 ++ hw/bsp/saml2x/boards/sensorwatch_m0/board.mk | 4 +- .../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/ From 1b97cec9957cfc06d3c2e4eab6d244e8a98aa271 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 3 May 2024 11:19:44 +0700 Subject: [PATCH 410/454] 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 From 6524e26e627999439465863e6bf87719e869ead8 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 3 May 2024 11:39:42 +0700 Subject: [PATCH 411/454] add cmake for stm32wb --- .github/workflows/build_arm.yml | 9 +- .github/workflows/build_cmake.yml | 4 +- hw/bsp/stm32f0/family.cmake | 88 ++++++------- hw/bsp/stm32f1/family.cmake | 88 ++++++------- hw/bsp/stm32f2/family.cmake | 88 ++++++------- hw/bsp/stm32f3/family.cmake | 84 +++++++------ hw/bsp/stm32f7/family.cmake | 92 +++++++------- hw/bsp/stm32h7/family.cmake | 96 +++++++------- hw/bsp/stm32l0/family.cmake | 90 ++++++------- hw/bsp/stm32l4/family.cmake | 88 ++++++------- hw/bsp/stm32u5/family.cmake | 92 +++++++------- .../boards/stm32wb55nucleo/board.cmake | 10 ++ .../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, 592 insertions(+), 456 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) + if (TARGET ${BOARD_TARGET}) + return() + endif() - set(LD_FILE_Clang ${LD_FILE_GNU}) - set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) + # 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) - 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}} + 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) + if (TARGET ${BOARD_TARGET}) + return() + endif() - 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 () +# 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) - 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}} + 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 ) - 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}" + ) + 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) + if (TARGET ${BOARD_TARGET}) + return() + endif() - 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 () + # 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) - 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}} + 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 ) - 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}" + ) + 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) + if (TARGET ${BOARD_TARGET}) + return() + endif() - set(LD_FILE_Clang ${LD_FILE_GNU}) - set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) + # 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) - 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}} + 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 ) - 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}" + ) + 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) + if (TARGET ${BOARD_TARGET}) + return() + endif() - set(LD_FILE_Clang ${LD_FILE_GNU}) - set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) + # 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) - 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}} + 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 ) - 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}" + ) + 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) + if (TARGET ${BOARD_TARGET}) + return() + endif() - 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() + # 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) - 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}} + 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 ) - 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}" + ) + 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) + if (TARGET ${BOARD_TARGET}) + return() + endif() - set(LD_FILE_Clang ${LD_FILE_GNU}) - set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) + # 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) - 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}} + 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) + if (TARGET ${BOARD_TARGET}) + return() + endif() - set(LD_FILE_Clang ${LD_FILE_GNU}) - set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) + # 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) - 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 - ) + 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}) + 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 () + 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) + if (TARGET ${BOARD_TARGET}) + return() + endif() - 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) + # 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) - 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}} + 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 ) - 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}" + ) + 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) \ From 43f4317a97d51eec2fdf90bcd545474fe97c77f3 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 3 May 2024 12:21:02 +0700 Subject: [PATCH 412/454] add missing FreeRTOSConfig.h --- hw/bsp/saml2x/FreeRTOSConfig/FreeRTOSConfig.h | 149 ++++++++++++++++++ .../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: [PATCH 413/454] - 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 +- .../{samd11d14am_flash.ld => cynthion_d11.ld} | 2 + .../samd11/boards/samd11_xplained/board.cmake | 8 + .../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 +- .../stm32wb/FreeRTOSConfig/FreeRTOSConfig.h | 6 +- tools/build_cmake.py | 2 +- 15 files changed, 332 insertions(+), 15 deletions(-) create mode 100644 hw/bsp/samd11/FreeRTOSConfig/FreeRTOSConfig.h create mode 100644 hw/bsp/samd11/boards/cynthion_d11/board.cmake rename hw/bsp/samd11/boards/cynthion_d11/{samd11d14am_flash.ld => cynthion_d11.ld} (99%) 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<= 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: From 4b86b492603cbb869b7cbcad704f92009b6c364f Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 3 May 2024 15:15:27 +0700 Subject: [PATCH 414/454] 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 ++++++++++ .../boards/d5035_01/board.mk | 2 +- .../boards/d5035_01/same51j19a_flash.ld | 2 + .../boards/feather_m4_express/board.cmake | 2 + .../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 + .../boards/metro_m4_express/board.cmake | 2 + .../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 + .../samd51/boards/same54_xplained/board.cmake | 10 + hw/bsp/samd51/boards/same54_xplained/board.h | 50 +++ .../boards/same54_xplained/board.mk | 7 +- .../same54_xplained/same54p20a_flash.ld | 3 + .../boards/same54_xplained/same54p20a_sram.ld | 3 + hw/bsp/samd51/family.c | 57 ++- hw/bsp/samd51/family.cmake | 19 +- hw/bsp/samd51/family.mk | 35 +- hw/bsp/same5x/boards/d5035_01/d5035_01.c | 353 ------------------ .../boards/same54_xplained/same54_xplained.c | 306 --------------- hw/bsp/same5x/family.mk | 38 -- .../saml2x/boards/atsaml21_xpro/board.cmake | 2 +- hw/bsp/saml2x/boards/atsaml21_xpro/board.mk | 2 +- .../saml2x/boards/saml22_feather/board.cmake | 2 +- hw/bsp/saml2x/boards/saml22_feather/board.mk | 2 +- .../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 +- 36 files changed, 403 insertions(+), 749 deletions(-) create mode 100644 hw/bsp/samd51/boards/d5035_01/board.cmake create mode 100644 hw/bsp/samd51/boards/d5035_01/board.h rename hw/bsp/{same5x => samd51}/boards/d5035_01/board.mk (95%) rename hw/bsp/{same5x => samd51}/boards/d5035_01/same51j19a_flash.ld (99%) create mode 100644 hw/bsp/samd51/boards/same54_xplained/board.cmake create mode 100644 hw/bsp/samd51/boards/same54_xplained/board.h rename hw/bsp/{same5x => samd51}/boards/same54_xplained/board.mk (54%) rename hw/bsp/{same5x => samd51}/boards/same54_xplained/same54p20a_flash.ld (99%) rename hw/bsp/{same5x => samd51}/boards/same54_xplained/same54p20a_sram.ld (99%) delete mode 100644 hw/bsp/same5x/boards/d5035_01/d5035_01.c delete mode 100644 hw/bsp/same5x/boards/same54_xplained/same54_xplained.c 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/same5x/boards/d5035_01/board.mk b/hw/bsp/samd51/boards/d5035_01/board.mk similarity index 95% rename from hw/bsp/same5x/boards/d5035_01/board.mk rename to hw/bsp/samd51/boards/d5035_01/board.mk index c53411bb8..4aa6b89fe 100644 --- a/hw/bsp/same5x/boards/d5035_01/board.mk +++ b/hw/bsp/samd51/boards/d5035_01/board.mk @@ -1,4 +1,4 @@ -MCU = same51 +SAM_FAMILY = same51 HWREV ?= 1 diff --git a/hw/bsp/same5x/boards/d5035_01/same51j19a_flash.ld b/hw/bsp/samd51/boards/d5035_01/same51j19a_flash.ld similarity index 99% rename from hw/bsp/same5x/boards/d5035_01/same51j19a_flash.ld rename to hw/bsp/samd51/boards/d5035_01/same51j19a_flash.ld index 486043f22..59afb604b 100644 --- a/hw/bsp/same5x/boards/d5035_01/same51j19a_flash.ld +++ b/hw/bsp/samd51/boards/d5035_01/same51j19a_flash.ld @@ -44,6 +44,8 @@ MEMORY /* 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 { 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/same5x/boards/same54_xplained/board.mk b/hw/bsp/samd51/boards/same54_xplained/board.mk similarity index 54% rename from hw/bsp/same5x/boards/same54_xplained/board.mk rename to hw/bsp/samd51/boards/same54_xplained/board.mk index 41cf95bfc..d10e9e34c 100644 --- a/hw/bsp/same5x/boards/same54_xplained/board.mk +++ b/hw/bsp/samd51/boards/same54_xplained/board.mk @@ -1,9 +1,6 @@ -MCU = same54 +SAM_FAMILY = same54 -CFLAGS += \ - -DCONF_CPU_FREQUENCY=48000000 \ - -D__SAME54P20A__ \ - -DBOARD_NAME="\"Microchip SAM E54 Xplained Pro\"" +CFLAGS += -D__SAME54P20A__ # All source paths should be relative to the top level. LD_FILE = $(BOARD_PATH)/same54p20a_flash.ld diff --git a/hw/bsp/same5x/boards/same54_xplained/same54p20a_flash.ld b/hw/bsp/samd51/boards/same54_xplained/same54p20a_flash.ld similarity index 99% rename from hw/bsp/same5x/boards/same54_xplained/same54p20a_flash.ld rename to hw/bsp/samd51/boards/same54_xplained/same54p20a_flash.ld index 7a7f1be46..8a9fd7d9f 100644 --- a/hw/bsp/same5x/boards/same54_xplained/same54p20a_flash.ld +++ b/hw/bsp/samd51/boards/same54_xplained/same54p20a_flash.ld @@ -44,6 +44,8 @@ MEMORY /* 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 { @@ -160,4 +162,5 @@ SECTIONS . = ALIGN(4); _end = . ; + end = .; } diff --git a/hw/bsp/same5x/boards/same54_xplained/same54p20a_sram.ld b/hw/bsp/samd51/boards/same54_xplained/same54p20a_sram.ld similarity index 99% rename from hw/bsp/same5x/boards/same54_xplained/same54p20a_sram.ld rename to hw/bsp/samd51/boards/same54_xplained/same54p20a_sram.ld index c768f9c9a..c88617729 100644 --- a/hw/bsp/same5x/boards/same54_xplained/same54p20a_sram.ld +++ b/hw/bsp/samd51/boards/same54_xplained/same54p20a_sram.ld @@ -43,6 +43,8 @@ MEMORY /* 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 { @@ -159,4 +161,5 @@ SECTIONS . = 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/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/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/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 \ From 59f8e9dff942baf7f0b05ef4927672ee2627f54b Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 3 May 2024 15:17:07 +0700 Subject: [PATCH 415/454] rename to samd5x_e5x --- .idea/cmake.xml | 40 +++++++++++++++++-- .idea/runConfigurations/rp2040.xml | 2 +- .../FreeRTOSConfig/FreeRTOSConfig.h | 0 .../boards/d5035_01/board.cmake | 0 .../boards/d5035_01/board.h | 0 .../boards/d5035_01/board.mk | 0 .../boards/d5035_01/same51j19a_flash.ld | 0 .../boards/feather_m4_express/board.cmake | 0 .../boards/feather_m4_express/board.h | 0 .../boards/feather_m4_express/board.mk | 0 .../feather_m4_express/feather_m4_express.ld | 0 .../boards/itsybitsy_m4/board.cmake | 0 .../boards/itsybitsy_m4/board.h | 0 .../boards/itsybitsy_m4/board.mk | 0 .../boards/itsybitsy_m4/itsybitsy_m4.ld | 0 .../boards/metro_m4_express/board.cmake | 0 .../boards/metro_m4_express/board.h | 0 .../boards/metro_m4_express/board.mk | 0 .../metro_m4_express/metro_m4_express.ld | 0 .../boards/pybadge/board.cmake | 0 .../boards/pybadge/board.h | 0 .../boards/pybadge/board.mk | 0 .../boards/pybadge/pybadge.ld | 0 .../boards/pyportal/board.cmake | 0 .../boards/pyportal/board.h | 0 .../boards/pyportal/board.mk | 0 .../boards/pyportal/pyportal.ld | 0 .../boards/same54_xplained/board.cmake | 0 .../boards/same54_xplained/board.h | 0 .../boards/same54_xplained/board.mk | 0 .../same54_xplained/same54p20a_flash.ld | 0 .../boards/same54_xplained/same54p20a_sram.ld | 0 hw/bsp/{samd51 => samd5x_e5x}/family.c | 0 hw/bsp/{samd51 => samd5x_e5x}/family.cmake | 0 hw/bsp/{samd51 => samd5x_e5x}/family.mk | 0 35 files changed, 38 insertions(+), 4 deletions(-) rename hw/bsp/{samd51 => samd5x_e5x}/FreeRTOSConfig/FreeRTOSConfig.h (100%) rename hw/bsp/{samd51 => samd5x_e5x}/boards/d5035_01/board.cmake (100%) rename hw/bsp/{samd51 => samd5x_e5x}/boards/d5035_01/board.h (100%) rename hw/bsp/{samd51 => samd5x_e5x}/boards/d5035_01/board.mk (100%) rename hw/bsp/{samd51 => samd5x_e5x}/boards/d5035_01/same51j19a_flash.ld (100%) rename hw/bsp/{samd51 => samd5x_e5x}/boards/feather_m4_express/board.cmake (100%) rename hw/bsp/{samd51 => samd5x_e5x}/boards/feather_m4_express/board.h (100%) rename hw/bsp/{samd51 => samd5x_e5x}/boards/feather_m4_express/board.mk (100%) rename hw/bsp/{samd51 => samd5x_e5x}/boards/feather_m4_express/feather_m4_express.ld (100%) rename hw/bsp/{samd51 => samd5x_e5x}/boards/itsybitsy_m4/board.cmake (100%) rename hw/bsp/{samd51 => samd5x_e5x}/boards/itsybitsy_m4/board.h (100%) rename hw/bsp/{samd51 => samd5x_e5x}/boards/itsybitsy_m4/board.mk (100%) rename hw/bsp/{samd51 => samd5x_e5x}/boards/itsybitsy_m4/itsybitsy_m4.ld (100%) rename hw/bsp/{samd51 => samd5x_e5x}/boards/metro_m4_express/board.cmake (100%) rename hw/bsp/{samd51 => samd5x_e5x}/boards/metro_m4_express/board.h (100%) rename hw/bsp/{samd51 => samd5x_e5x}/boards/metro_m4_express/board.mk (100%) rename hw/bsp/{samd51 => samd5x_e5x}/boards/metro_m4_express/metro_m4_express.ld (100%) rename hw/bsp/{samd51 => samd5x_e5x}/boards/pybadge/board.cmake (100%) rename hw/bsp/{samd51 => samd5x_e5x}/boards/pybadge/board.h (100%) rename hw/bsp/{samd51 => samd5x_e5x}/boards/pybadge/board.mk (100%) rename hw/bsp/{samd51 => samd5x_e5x}/boards/pybadge/pybadge.ld (100%) rename hw/bsp/{samd51 => samd5x_e5x}/boards/pyportal/board.cmake (100%) rename hw/bsp/{samd51 => samd5x_e5x}/boards/pyportal/board.h (100%) rename hw/bsp/{samd51 => samd5x_e5x}/boards/pyportal/board.mk (100%) rename hw/bsp/{samd51 => samd5x_e5x}/boards/pyportal/pyportal.ld (100%) rename hw/bsp/{samd51 => samd5x_e5x}/boards/same54_xplained/board.cmake (100%) rename hw/bsp/{samd51 => samd5x_e5x}/boards/same54_xplained/board.h (100%) rename hw/bsp/{samd51 => samd5x_e5x}/boards/same54_xplained/board.mk (100%) rename hw/bsp/{samd51 => samd5x_e5x}/boards/same54_xplained/same54p20a_flash.ld (100%) rename hw/bsp/{samd51 => samd5x_e5x}/boards/same54_xplained/same54p20a_sram.ld (100%) rename hw/bsp/{samd51 => samd5x_e5x}/family.c (100%) rename hw/bsp/{samd51 => samd5x_e5x}/family.cmake (100%) rename hw/bsp/{samd51 => samd5x_e5x}/family.mk (100%) 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/samd5x_e5x/FreeRTOSConfig/FreeRTOSConfig.h similarity index 100% rename from hw/bsp/samd51/FreeRTOSConfig/FreeRTOSConfig.h rename to hw/bsp/samd5x_e5x/FreeRTOSConfig/FreeRTOSConfig.h diff --git a/hw/bsp/samd51/boards/d5035_01/board.cmake b/hw/bsp/samd5x_e5x/boards/d5035_01/board.cmake similarity index 100% rename from hw/bsp/samd51/boards/d5035_01/board.cmake rename to hw/bsp/samd5x_e5x/boards/d5035_01/board.cmake diff --git a/hw/bsp/samd51/boards/d5035_01/board.h b/hw/bsp/samd5x_e5x/boards/d5035_01/board.h similarity index 100% rename from hw/bsp/samd51/boards/d5035_01/board.h rename to hw/bsp/samd5x_e5x/boards/d5035_01/board.h diff --git a/hw/bsp/samd51/boards/d5035_01/board.mk b/hw/bsp/samd5x_e5x/boards/d5035_01/board.mk similarity index 100% rename from hw/bsp/samd51/boards/d5035_01/board.mk rename to hw/bsp/samd5x_e5x/boards/d5035_01/board.mk diff --git a/hw/bsp/samd51/boards/d5035_01/same51j19a_flash.ld b/hw/bsp/samd5x_e5x/boards/d5035_01/same51j19a_flash.ld similarity index 100% rename from hw/bsp/samd51/boards/d5035_01/same51j19a_flash.ld rename to hw/bsp/samd5x_e5x/boards/d5035_01/same51j19a_flash.ld diff --git a/hw/bsp/samd51/boards/feather_m4_express/board.cmake b/hw/bsp/samd5x_e5x/boards/feather_m4_express/board.cmake similarity index 100% rename from hw/bsp/samd51/boards/feather_m4_express/board.cmake rename to hw/bsp/samd5x_e5x/boards/feather_m4_express/board.cmake diff --git a/hw/bsp/samd51/boards/feather_m4_express/board.h b/hw/bsp/samd5x_e5x/boards/feather_m4_express/board.h similarity index 100% rename from hw/bsp/samd51/boards/feather_m4_express/board.h rename to hw/bsp/samd5x_e5x/boards/feather_m4_express/board.h diff --git a/hw/bsp/samd51/boards/feather_m4_express/board.mk b/hw/bsp/samd5x_e5x/boards/feather_m4_express/board.mk similarity index 100% rename from hw/bsp/samd51/boards/feather_m4_express/board.mk rename to hw/bsp/samd5x_e5x/boards/feather_m4_express/board.mk diff --git a/hw/bsp/samd51/boards/feather_m4_express/feather_m4_express.ld b/hw/bsp/samd5x_e5x/boards/feather_m4_express/feather_m4_express.ld similarity index 100% rename from hw/bsp/samd51/boards/feather_m4_express/feather_m4_express.ld rename to hw/bsp/samd5x_e5x/boards/feather_m4_express/feather_m4_express.ld diff --git a/hw/bsp/samd51/boards/itsybitsy_m4/board.cmake b/hw/bsp/samd5x_e5x/boards/itsybitsy_m4/board.cmake similarity index 100% rename from hw/bsp/samd51/boards/itsybitsy_m4/board.cmake rename to hw/bsp/samd5x_e5x/boards/itsybitsy_m4/board.cmake diff --git a/hw/bsp/samd51/boards/itsybitsy_m4/board.h b/hw/bsp/samd5x_e5x/boards/itsybitsy_m4/board.h similarity index 100% rename from hw/bsp/samd51/boards/itsybitsy_m4/board.h rename to hw/bsp/samd5x_e5x/boards/itsybitsy_m4/board.h diff --git a/hw/bsp/samd51/boards/itsybitsy_m4/board.mk b/hw/bsp/samd5x_e5x/boards/itsybitsy_m4/board.mk similarity index 100% rename from hw/bsp/samd51/boards/itsybitsy_m4/board.mk rename to hw/bsp/samd5x_e5x/boards/itsybitsy_m4/board.mk diff --git a/hw/bsp/samd51/boards/itsybitsy_m4/itsybitsy_m4.ld b/hw/bsp/samd5x_e5x/boards/itsybitsy_m4/itsybitsy_m4.ld similarity index 100% rename from hw/bsp/samd51/boards/itsybitsy_m4/itsybitsy_m4.ld rename to hw/bsp/samd5x_e5x/boards/itsybitsy_m4/itsybitsy_m4.ld diff --git a/hw/bsp/samd51/boards/metro_m4_express/board.cmake b/hw/bsp/samd5x_e5x/boards/metro_m4_express/board.cmake similarity index 100% rename from hw/bsp/samd51/boards/metro_m4_express/board.cmake rename to hw/bsp/samd5x_e5x/boards/metro_m4_express/board.cmake diff --git a/hw/bsp/samd51/boards/metro_m4_express/board.h b/hw/bsp/samd5x_e5x/boards/metro_m4_express/board.h similarity index 100% rename from hw/bsp/samd51/boards/metro_m4_express/board.h rename to hw/bsp/samd5x_e5x/boards/metro_m4_express/board.h diff --git a/hw/bsp/samd51/boards/metro_m4_express/board.mk b/hw/bsp/samd5x_e5x/boards/metro_m4_express/board.mk similarity index 100% rename from hw/bsp/samd51/boards/metro_m4_express/board.mk rename to hw/bsp/samd5x_e5x/boards/metro_m4_express/board.mk diff --git a/hw/bsp/samd51/boards/metro_m4_express/metro_m4_express.ld b/hw/bsp/samd5x_e5x/boards/metro_m4_express/metro_m4_express.ld similarity index 100% rename from hw/bsp/samd51/boards/metro_m4_express/metro_m4_express.ld rename to hw/bsp/samd5x_e5x/boards/metro_m4_express/metro_m4_express.ld diff --git a/hw/bsp/samd51/boards/pybadge/board.cmake b/hw/bsp/samd5x_e5x/boards/pybadge/board.cmake similarity index 100% rename from hw/bsp/samd51/boards/pybadge/board.cmake rename to hw/bsp/samd5x_e5x/boards/pybadge/board.cmake diff --git a/hw/bsp/samd51/boards/pybadge/board.h b/hw/bsp/samd5x_e5x/boards/pybadge/board.h similarity index 100% rename from hw/bsp/samd51/boards/pybadge/board.h rename to hw/bsp/samd5x_e5x/boards/pybadge/board.h diff --git a/hw/bsp/samd51/boards/pybadge/board.mk b/hw/bsp/samd5x_e5x/boards/pybadge/board.mk similarity index 100% rename from hw/bsp/samd51/boards/pybadge/board.mk rename to hw/bsp/samd5x_e5x/boards/pybadge/board.mk diff --git a/hw/bsp/samd51/boards/pybadge/pybadge.ld b/hw/bsp/samd5x_e5x/boards/pybadge/pybadge.ld similarity index 100% rename from hw/bsp/samd51/boards/pybadge/pybadge.ld rename to hw/bsp/samd5x_e5x/boards/pybadge/pybadge.ld diff --git a/hw/bsp/samd51/boards/pyportal/board.cmake b/hw/bsp/samd5x_e5x/boards/pyportal/board.cmake similarity index 100% rename from hw/bsp/samd51/boards/pyportal/board.cmake rename to hw/bsp/samd5x_e5x/boards/pyportal/board.cmake diff --git a/hw/bsp/samd51/boards/pyportal/board.h b/hw/bsp/samd5x_e5x/boards/pyportal/board.h similarity index 100% rename from hw/bsp/samd51/boards/pyportal/board.h rename to hw/bsp/samd5x_e5x/boards/pyportal/board.h diff --git a/hw/bsp/samd51/boards/pyportal/board.mk b/hw/bsp/samd5x_e5x/boards/pyportal/board.mk similarity index 100% rename from hw/bsp/samd51/boards/pyportal/board.mk rename to hw/bsp/samd5x_e5x/boards/pyportal/board.mk diff --git a/hw/bsp/samd51/boards/pyportal/pyportal.ld b/hw/bsp/samd5x_e5x/boards/pyportal/pyportal.ld similarity index 100% rename from hw/bsp/samd51/boards/pyportal/pyportal.ld rename to hw/bsp/samd5x_e5x/boards/pyportal/pyportal.ld diff --git a/hw/bsp/samd51/boards/same54_xplained/board.cmake b/hw/bsp/samd5x_e5x/boards/same54_xplained/board.cmake similarity index 100% rename from hw/bsp/samd51/boards/same54_xplained/board.cmake rename to hw/bsp/samd5x_e5x/boards/same54_xplained/board.cmake diff --git a/hw/bsp/samd51/boards/same54_xplained/board.h b/hw/bsp/samd5x_e5x/boards/same54_xplained/board.h similarity index 100% rename from hw/bsp/samd51/boards/same54_xplained/board.h rename to hw/bsp/samd5x_e5x/boards/same54_xplained/board.h diff --git a/hw/bsp/samd51/boards/same54_xplained/board.mk b/hw/bsp/samd5x_e5x/boards/same54_xplained/board.mk similarity index 100% rename from hw/bsp/samd51/boards/same54_xplained/board.mk rename to hw/bsp/samd5x_e5x/boards/same54_xplained/board.mk diff --git a/hw/bsp/samd51/boards/same54_xplained/same54p20a_flash.ld b/hw/bsp/samd5x_e5x/boards/same54_xplained/same54p20a_flash.ld similarity index 100% rename from hw/bsp/samd51/boards/same54_xplained/same54p20a_flash.ld rename to hw/bsp/samd5x_e5x/boards/same54_xplained/same54p20a_flash.ld diff --git a/hw/bsp/samd51/boards/same54_xplained/same54p20a_sram.ld b/hw/bsp/samd5x_e5x/boards/same54_xplained/same54p20a_sram.ld similarity index 100% rename from hw/bsp/samd51/boards/same54_xplained/same54p20a_sram.ld rename to hw/bsp/samd5x_e5x/boards/same54_xplained/same54p20a_sram.ld diff --git a/hw/bsp/samd51/family.c b/hw/bsp/samd5x_e5x/family.c similarity index 100% rename from hw/bsp/samd51/family.c rename to hw/bsp/samd5x_e5x/family.c diff --git a/hw/bsp/samd51/family.cmake b/hw/bsp/samd5x_e5x/family.cmake similarity index 100% rename from hw/bsp/samd51/family.cmake rename to hw/bsp/samd5x_e5x/family.cmake diff --git a/hw/bsp/samd51/family.mk b/hw/bsp/samd5x_e5x/family.mk similarity index 100% rename from hw/bsp/samd51/family.mk rename to hw/bsp/samd5x_e5x/family.mk From 704412bb481c285dded617aacb29c7346baf6bf4 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 3 May 2024 16:15:29 +0700 Subject: [PATCH 416/454] 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 ++ .../boards/ek_tm4c123gxl/board.h | 0 .../boards/ek_tm4c123gxl/board.mk | 2 + .../boards/ek_tm4c123gxl/tm4c123.ld | 21 +-- hw/bsp/{tm4c123 => tm4c}/family.c | 0 hw/bsp/tm4c/family.cmake | 95 +++++++++++ hw/bsp/tm4c/family.mk | 28 ++++ hw/bsp/tm4c123/family.mk | 30 ---- tools/get_deps.py | 7 +- 12 files changed, 304 insertions(+), 46 deletions(-) create mode 100644 hw/bsp/tm4c/FreeRTOSConfig/FreeRTOSConfig.h create mode 100644 hw/bsp/tm4c/boards/ek_tm4c123gxl/board.cmake rename hw/bsp/{tm4c123 => tm4c}/boards/ek_tm4c123gxl/board.h (100%) rename hw/bsp/{tm4c123 => tm4c}/boards/ek_tm4c123gxl/board.mk (90%) rename hw/bsp/{tm4c123 => tm4c}/boards/ek_tm4c123gxl/tm4c123.ld (77%) rename hw/bsp/{tm4c123 => tm4c}/family.c (100%) create mode 100644 hw/bsp/tm4c/family.cmake create mode 100644 hw/bsp/tm4c/family.mk 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 @@ -52,14 +53,14 @@ SECTIONS . = 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 + /* 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/tm4c/family.c similarity index 100% rename from hw/bsp/tm4c123/family.c rename to hw/bsp/tm4c/family.c 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/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'], From f38fbbfb2b663cf0977417cf313345f56475cdad Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 3 May 2024 16:48:55 +0700 Subject: [PATCH 417/454] add cmake for xmc4000 --- .github/workflows/build_arm.yml | 1 - .github/workflows/build_cmake.yml | 1 + .../xmc4000/FreeRTOSConfig/FreeRTOSConfig.h | 149 ++++++++++++++++++ .../xmc4000/boards/xmc4500_relax/board.cmake | 10 ++ hw/bsp/xmc4000/boards/xmc4500_relax/board.mk | 2 +- .../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: [PATCH 418/454] 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. */ From 58248f3e7fd05374d9b4779afb4cb158be96874f Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 3 May 2024 23:15:14 +0700 Subject: [PATCH 419/454] 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 From 7c7be885b405c7a954a0538e36a2f1b47fdb82f3 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 3 May 2024 23:16:21 +0700 Subject: [PATCH 420/454] 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 From f1940439e419e2a1c72a284158e098bca70f279a Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 4 May 2024 10:07:54 +0700 Subject: [PATCH 421/454] 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', From 666702f478dd91d5d2ea4f194d77f835844a19cd Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 4 May 2024 10:28:47 +0700 Subject: [PATCH 422/454] 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 From c020a0190d5f22c0f761ce0a5ec4a6e35e4d0662 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 4 May 2024 12:36:40 +0700 Subject: [PATCH 423/454] add cmake for f1c100s --- .../build_system/cmake/cpu/arm1176jzf-s.cmake | 2 + .../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 => family.c} | 46 ++++--- hw/bsp/f1c100s/family.cmake | 114 ++++++++++++++++++ hw/bsp/f1c100s/family.mk | 58 +++++++++ src/portable/sunxi/dcd_sunxi_musb.c | 14 ++- 12 files changed, 243 insertions(+), 84 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 rename hw/bsp/f1c100s/{f1c100s.c => family.c} (78%) 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/family.c similarity index 78% rename from hw/bsp/f1c100s/f1c100s.c rename to hw/bsp/f1c100s/family.c index 272b756f2..6df4a0ed8 100644 --- a/hw/bsp/f1c100s/f1c100s.c +++ b/hw/bsp/f1c100s/family.c @@ -39,10 +39,9 @@ extern void sys_uart_putc(char c); static void timer_init(void); -void board_init(void) -{ +void board_init(void) { arch_local_irq_disable(); - do_init_mem_pool(); + do_init_mem_pool(); f1c100s_intc_init(); timer_init(); printf("Timer INIT done\n"); @@ -50,42 +49,38 @@ void board_init(void) } // No LED, no button -void board_led_write(bool state) -{ - +void board_led_write(bool state) { + (void) state; } -uint32_t board_button_read(void) -{ +uint32_t board_button_read(void) { return 0; } -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--) { - sys_uart_putc(*(uint8_t const*)buf); + sys_uart_putc(*(uint8_t const*) buf); buf++; } return len; } -#if CFG_TUSB_OS == OPT_OS_NONE +#if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; -uint32_t board_millis(void) -{ +uint32_t board_millis(void) { return system_ticks; } -static void timer_handler(void) -{ - volatile uint32_t *temp_addr = (uint32_t *)(0x01C20C00 + 0x04); +static void timer_handler(void) { + volatile uint32_t* temp_addr = (uint32_t*) (0x01C20C00 + 0x04); /* clear timer */ *temp_addr |= 0x01; @@ -95,36 +90,37 @@ static void timer_handler(void) static void timer_init(void) { uint32_t temp; - volatile uint32_t *temp_addr; + volatile uint32_t* temp_addr; /* reload value */ temp = 12000000 / 1000; - temp_addr = (uint32_t *)(0x01C20C00 + 0x14); + 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 = (uint32_t*) (0x01C20C00 + 0x10); *temp_addr &= 0xffffff00; *temp_addr |= temp; /* open timer irq */ temp = 0x01 << 0; - temp_addr = (uint32_t *)(0x01C20C00); + temp_addr = (uint32_t*) (0x01C20C00); *temp_addr |= temp; /* set init value */ - temp_addr = (uint32_t *)(0x01C20C00 + 0x18); + temp_addr = (uint32_t*) (0x01C20C00 + 0x18); *temp_addr = 0; /* begin run timer */ temp = 0x01 << 0; - temp_addr = (uint32_t *)(0x01C20C00 + 0x10); + 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; From 3791514908c768df18df1be0afdcb07f2c3596b7 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 4 May 2024 17:23:16 +0700 Subject: [PATCH 424/454] add cmake for samg55 --- .github/workflows/build_cmake.yml | 2 +- .idea/cmake.xml | 10 +- hw/bsp/samg/FreeRTOSConfig/FreeRTOSConfig.h | 149 ++++++++++++++++++ .../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 + .../samg55_xplained}/samg55j19_flash.ld | 4 +- .../samg55xplained.c => samg/family.c} | 114 +++++++------- hw/bsp/samg/family.cmake | 114 ++++++++++++++ hw/bsp/samg/family.mk | 45 ++++++ .../hpl_usart_config.h | 0 .../peripheral_clk_config.h | 4 + hw/bsp/samg55xplained/board.mk | 56 ------- 13 files changed, 404 insertions(+), 120 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 rename hw/bsp/{samg55xplained => samg/boards/samg55_xplained}/samg55j19_flash.ld (97%) rename hw/bsp/{samg55xplained/samg55xplained.c => samg/family.c} (59%) create mode 100644 hw/bsp/samg/family.cmake create mode 100644 hw/bsp/samg/family.mk rename hw/bsp/{samg55xplained => samg}/hpl_usart_config.h (100%) rename hw/bsp/{samg55xplained => samg}/peripheral_clk_config.h (96%) delete mode 100644 hw/bsp/samg55xplained/board.mk 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< USB Clock Source // <0=> USB Clock Controller (USB_48M) 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 $< From ea55537fb2a42e112c8d4f714c71c51b2faa88d6 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Sun, 5 May 2024 20:33:01 +0200 Subject: [PATCH 425/454] 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_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_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_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) { From cc70958c16f4b88c0e48590d32189c870091547e Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Sun, 5 May 2024 21:18:57 +0200 Subject: [PATCH 426/454] 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 ; From d79c71abf593b7fde1e83eac074900216643dbff Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 6 May 2024 10:52:52 +0700 Subject: [PATCH 427/454] 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() From 497785393de5500d99ff80110040c04039bd072f Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 6 May 2024 17:14:35 +0700 Subject: [PATCH 428/454] 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 +++++++++++++++ .../boards/mm32f327x_bluepillplus/board.mk | 11 -- .../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 +- .../boards/mm32f327x_pitaya_lite/board.cmake | 10 + .../mm32/boards/mm32f327x_pitaya_lite/board.h | 14 ++ .../boards/mm32f327x_pitaya_lite/board.mk | 5 +- .../mm32f327x_pitaya_lite.c | 182 ------------------ .../mm32f327x_mb39.c => family.c} | 118 ++++++------ hw/bsp/mm32/family.cmake | 101 ++++++++++ hw/bsp/mm32/family.mk | 28 +-- tools/get_deps.py | 2 +- 16 files changed, 384 insertions(+), 614 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 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 rename hw/bsp/mm32/{boards/mm32f327x_mb39/mm32f327x_mb39.c => family.c} (63%) 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_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/boards/mm32f327x_mb39/mm32f327x_mb39.c b/hw/bsp/mm32/family.c similarity index 63% rename from hw/bsp/mm32/boards/mm32f327x_mb39/mm32f327x_mb39.c rename to hw/bsp/mm32/family.c index 086532179..f22fd90a1 100644 --- a/hw/bsp/mm32/boards/mm32f327x_mb39/mm32f327x_mb39.c +++ b/hw/bsp/mm32/family.c @@ -24,21 +24,20 @@ * This file is part of the TinyUSB stack. */ -#include "mm32_device.h" #include "hal_conf.h" -#include "tusb.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) -{ +void OTG_FS_IRQHandler(void) { tud_int_handler(0); - } -void USB_DeviceClockInit (void) -{ + +void USB_DeviceClockInit(void) { /* Select USBCLK source */ // RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_Div1); RCC->CFGR &= ~(0x3 << 22); @@ -50,122 +49,121 @@ void USB_DeviceClockInit (void) //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ -// LED extern u32 SystemCoreClock; -const int baudrate = 115200; -void board_init (void) -{ +void board_init(void) { // usb clock USB_DeviceClockInit(); - if ( SysTick_Config(SystemCoreClock / 1000) ) - { - while ( 1 ) - ; + if (SysTick_Config(SystemCoreClock / 1000)) { + while (1); } NVIC_SetPriority(SysTick_IRQn, 0x0); + RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE); + // 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_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 - RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE); // - //UART initialset - - GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_7); - GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_7); + 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 = baudrate; + UART_InitStruct.UART_BaudRate = CFG_BOARD_UART_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_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(UART1, &UART_InitStruct); //initial uart 1 - UART_Cmd(UART1, ENABLE); //enable uart 1 + UART_Init(UART_DEV, &UART_InitStruct); + UART_Cmd(UART_DEV, ENABLE); - //UART1_TX GPIOA.9 GPIO_StructInit(&GPIO_InitStruct); - GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; + 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(GPIOA, &GPIO_InitStruct); + GPIO_Init(UART_GPIO_PORT, &GPIO_InitStruct); - //UART1_RX GPIOA.10 - GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5; + GPIO_InitStruct.GPIO_Pin = 1 << UART_RX_PIN; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; - GPIO_Init(GPIOA, &GPIO_InitStruct); - + GPIO_Init(UART_GPIO_PORT, &GPIO_InitStruct); + #endif } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ -void board_led_write (bool state) -{ - state ? (GPIO_ResetBits(GPIOA, GPIO_Pin_15)) : (GPIO_SetBits(GPIOA, GPIO_Pin_15)); +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) -{ +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) -{ +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 +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) -{ + +void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis (void) -{ +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) -{ - +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', From a9f1c62dffc2cb0229767959173f78eec9931db0 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 6 May 2024 17:28:48 +0700 Subject: [PATCH 429/454] temp fix for mm32 redundant-decls of SystemCoreClock --- hw/bsp/mm32/family.c | 24 ++++++++++++------- .../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; From dfda0b124f4e436e81770cb4986523da1036f654 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 6 May 2024 17:31:00 +0700 Subject: [PATCH 430/454] 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 From 91d69fa942c8a450c9816595f0d19138964533ef Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Tue, 7 May 2024 00:10:26 +0200 Subject: [PATCH 431/454] Reformat NCM class. --- src/class/net/ncm.h | 141 ++-- src/class/net/ncm_device.c | 1238 ++++++++++++++++-------------------- 2 files changed, 624 insertions(+), 755 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 + // 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 + // 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 + // 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 + // 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); +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_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 + 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; } + } + 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 - 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 - - - -static xmit_ntb_t *xmit_get_free_ntb(void) /** * Get an NTB from the free list */ -{ - TU_LOG3("xmit_get_free_ntb()\n"); +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; - } + 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 + } + 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; +static xmit_ntb_t *xmit_get_next_ready_ntb(void) { + 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; + 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_LOG3("recv_get_next_ready_ntb: %p\n", r); - return r; -} // xmit_get_next_ready_ntb + 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); +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); - if (xferred_bytes == 0 || xferred_bytes % CFG_TUD_NET_ENDPOINT_SIZE != 0) { - return false; - } + if (xferred_bytes == 0 || xferred_bytes % CFG_TUD_NET_ENDPOINT_SIZE != 0) { + return false; + } - TU_ASSERT(ncm_interface.itf_data_alt == 1, false); - TU_ASSERT( !usbd_edpt_busy(rhport, ncm_interface.ep_in), false); + 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); + 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); + // start transmission of the ZLP + usbd_edpt_xfer(rhport, ncm_interface.ep_in, NULL, 0); - return true; -} // xmit_insert_required_zlp + 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"); +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_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; + 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; + } - 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 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_LOG_DRV(">> %d %d\n", ncm_interface.xmit_tinyusb_ntb->nth.wBlockLength, ncm_interface.xmit_glue_ntb_datagram_ndx); + } - 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 - // 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); +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 + 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 = 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; + } - ncm_interface.xmit_glue_ntb_datagram_ndx = 0; + ncm_interface.xmit_glue_ntb_datagram_ndx = 0; - xmit_ntb_t *ntb = ncm_interface.xmit_glue_ntb; + 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 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 + // 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"); +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; - } + 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 + } + 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); +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; - } + 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; - } + 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 + // 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); +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, %d)\n", ntb, (int)len); + TU_LOG_DRV("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; - } + // 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; + } - // - // check (first) NDP(16) - // - const ndp16_t *ndp16 = (const ndp16_t *)(ntb->data + nth16->wNdpIndex); + // check (first) NDP(16) + const ndp16_t *ndp16 = (const ndp16_t *) (ntb->data + nth16->wNdpIndex); - 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->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; + } + + 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)); + + 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->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; + 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; + } - 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)); + #if CFG_TUD_NCM_LOG_LEVEL >= 3 + TU_LOG_BUF(3, ntb->data[i], len); + #endif - 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; - } + // -> ntb contains a valid packet structure + // ok... I did not check for garbage within the datagram indices... + return true; +} // recv_validate_datagram -#if CFG_TUSB_DEBUG >= 3 - for (uint32_t i = 0; i < len; ++i) { - TU_LOG3(" %02x", ntb->data[i]); - } - TU_LOG3("\n"); -#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"); +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_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) { + 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; + } + } } - - 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; - } - } - } - } -} // 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); +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); + 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 + 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); +void tud_network_xmit(void *ref, uint16_t arg) { + TU_LOG_DRV("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; - } + if (ncm_interface.xmit_glue_ntb == NULL) { + TU_LOG_DRV("(EE) tud_network_xmit: no buffer\n");// must not happen (really) + return; + } - xmit_ntb_t *ntb = ncm_interface.xmit_glue_ntb; + 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); + // 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; + // 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; - ntb->nth.wBlockLength += (uint16_t)(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) { - TU_LOG1("(EE) tud_network_xmit: buffer overflow\n"); // must not happen (really) - return; - } + 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 + 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)); + 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 + 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; +void netd_reset(uint8_t rhport) { + (void) rhport; - TU_LOG3("netd_reset(%d)\n", 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); +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 - 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); + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + } - return drv_len; -} // netd_open + // 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; +bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t 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) { - // - // 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); + 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); } - 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); + 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 + 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); - - if (stage != CONTROL_STAGE_SETUP) { - return true; - } - - 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 ; - } - +bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) { + if (stage != CONTROL_STAGE_SETUP) { return true; -} // netd_control_xfer_cb + } -#endif // ECLIPSE_GUI || ( CFG_TUD_ENABLED && CFG_TUD_NCM ) + 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); + + 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; + + 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 ) From d25ee82d3f689dcf22e44246b61f58756195581d Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Tue, 7 May 2024 00:17:09 +0200 Subject: [PATCH 432/454] Reformat net_lwip_webserver example. --- examples/device/net_lwip_webserver/src/main.c | 113 +++++++----------- .../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_ */ From 63d5103f42f5da11e08566a107c85b358e3d11aa Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Tue, 7 May 2024 00:18:31 +0200 Subject: [PATCH 433/454] 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 From 0f4ea8e9182c3f1f526e2ff5447ca31c5c7d8709 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Tue, 7 May 2024 00:23:50 +0200 Subject: [PATCH 434/454] 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 ++++++++ .../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 From e5d92c4ea736669445d728d6374f0e1b00c9eb15 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Tue, 7 May 2024 00:37:57 +0200 Subject: [PATCH 435/454] 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 From d01b2cfc0e25e6d64f8d7a2d764c2620e0d9d71f Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Tue, 7 May 2024 20:17:48 +1000 Subject: [PATCH 436/454] 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 From 1cab553f4bcb6633face4f50f03192928a68f751 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 9 May 2024 13:55:18 +0200 Subject: [PATCH 437/454] 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; From ba6babf570752a28379aab51d9c27e7b9efe872d Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Thu, 9 May 2024 20:43:46 +0700 Subject: [PATCH 438/454] 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 ++ .../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 +- .../build_system/cmake/cpu/rv32i-ilp32.cmake | 19 ++ .../cmake/cpu/rv32imac-ilp32.cmake | 18 ++ .../cmake/toolchain/riscv_gcc.cmake | 21 ++ examples/build_system/make/cpu/rv32i-ilp32.mk | 13 + .../build_system/make/cpu/rv32imac-ilp32.mk | 13 + .../build_system/make/toolchain/riscv_gcc.mk | 20 ++ examples/device/video_capture/skip.txt | 1 - .../boards/ch32v307v_r1_1v0/board.cmake | 4 + .../ch32v307v_r1_1v0 => }/debug_uart.c | 0 .../ch32v307v_r1_1v0 => }/debug_uart.h | 0 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/{fomu.c => family.c} | 3 +- hw/bsp/fomu/family.cmake | 91 ++++++ hw/bsp/fomu/family.mk | 9 +- .../boards/sipeed_longan_nano/board.cmake | 13 + .../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/{hil_hfp.json => hfp.json} | 0 test/hil/hil_test.py | 69 ++-- test/hil/{hil_pi4.json => pi4.json} | 10 - 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 +++- 53 files changed, 1170 insertions(+), 845 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 rename hw/bsp/ch32v307/{boards/ch32v307v_r1_1v0 => }/debug_uart.c (100%) rename hw/bsp/ch32v307/{boards/ch32v307v_r1_1v0 => }/debug_uart.h (100%) 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 rename hw/bsp/fomu/{fomu.c => family.c} (99%) create mode 100644 hw/bsp/fomu/family.cmake create mode 100644 hw/bsp/gd32vf103/boards/sipeed_longan_nano/board.cmake create mode 100644 hw/bsp/gd32vf103/family.cmake rename test/hil/{hil_hfp.json => hfp.json} (100%) rename test/hil/{hil_pi4.json => pi4.json} (72%) 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: + set-matrix: 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: - 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' + - name: Generate matrix json + id: set-matrix-json 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 - 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/debug_uart.c similarity index 100% rename from hw/bsp/ch32v307/boards/ch32v307v_r1_1v0/debug_uart.c rename to hw/bsp/ch32v307/debug_uart.c diff --git a/hw/bsp/ch32v307/boards/ch32v307v_r1_1v0/debug_uart.h b/hw/bsp/ch32v307/debug_uart.h similarity index 100% rename from hw/bsp/ch32v307/boards/ch32v307v_r1_1v0/debug_uart.h rename to hw/bsp/ch32v307/debug_uart.h 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/fomu.c b/hw/bsp/fomu/family.c similarity index 99% rename from hw/bsp/fomu/fomu.c rename to hw/bsp/fomu/family.c index d155b743d..ccf2b12f4 100644 --- a/hw/bsp/fomu/fomu.c +++ b/hw/bsp/fomu/family.c @@ -26,10 +26,11 @@ #include #include -#include "../board_api.h" #include "csr.h" #include "irq.h" +#include "bsp/board_api.h" + //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ 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/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/hil_hfp.json b/test/hil/hfp.json similarity index 100% rename from test/hil/hil_hfp.json rename to test/hil/hfp.json 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/hil_pi4.json b/test/hil/pi4.json similarity index 72% rename from test/hil/hil_pi4.json rename to test/hil/pi4.json index 8aff81910..04329bb64 100644 --- a/test/hil/hil_pi4.json +++ b/test/hil/pi4.json @@ -7,16 +7,6 @@ "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", 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()) From 2b9e53772e73c2bfd07bbbf4d6d2f0b33bcd22fb Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 9 May 2024 16:28:25 +0200 Subject: [PATCH 439/454] 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; From 015b57b6ef5cd24db8665c62e8fe209bce3e2b7e Mon Sep 17 00:00:00 2001 From: John Toniutti Date: Thu, 9 May 2024 17:05:14 +0200 Subject: [PATCH 440/454] 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 //--------------------------------------------------------------------+ From c8beaad2b18b4417ec763fc3dc85476a6480a2f4 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 9 May 2024 18:07:22 +0200 Subject: [PATCH 441/454] 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); From 11b5b2af51df9602b29728caf2ceb47dca61d835 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 9 May 2024 18:34:07 +0200 Subject: [PATCH 442/454] 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) { From ca479d6e4b8e034dda7026fa1f229d16001d61c2 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 9 May 2024 18:44:27 +0200 Subject: [PATCH 443/454] 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); From f09fa22bbce6139810db785940c56c5048794f31 Mon Sep 17 00:00:00 2001 From: John Toniutti Date: Thu, 9 May 2024 18:45:20 +0200 Subject: [PATCH 444/454] 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 From 16cd92fbf13170a027560fa58837f209381229cd Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 9 May 2024 21:47:22 +0200 Subject: [PATCH 445/454] 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: From 376b43906a901a878a07aca1cd364e32b839e656 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 9 May 2024 21:55:28 +0200 Subject: [PATCH 446/454] 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 From eea7d7b327a208fc5934feed2c19a6bfe3414b0b Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 9 May 2024 22:00:34 +0200 Subject: [PATCH 447/454] 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 From 36ba42cc0f3f14b6a15fe3ee3a534319e2d89c81 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 9 May 2024 22:57:25 +0200 Subject: [PATCH 448/454] 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); } } From 2f5db37c1aea932845c2de8fe5bb4b1b08b24722 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 10 May 2024 10:30:47 +0700 Subject: [PATCH 449/454] 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) From 15e2ccf1b3b7c53a90550e637285c00c88a4a3fe Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Fri, 10 May 2024 12:44:54 +0700 Subject: [PATCH 450/454] 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 From 8d63d9368edaec0385af20d615a0acba51f77beb Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Fri, 10 May 2024 13:00:19 +0700 Subject: [PATCH 451/454] 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 From 81ceb837b9feb3971056196f6a67234c4012352b Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Fri, 10 May 2024 17:53:26 +0700 Subject: [PATCH 452/454] 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 From 3e2ea7750681b27238043c7158ff5508f01914a3 Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Fri, 10 May 2024 18:55:43 +0700 Subject: [PATCH 453/454] 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 --- .../{prepare_build => get_deps}/action.yml | 23 ++-- .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 +- 24 files changed, 296 insertions(+), 443 deletions(-) rename .github/actions/{prepare_build => get_deps}/action.yml (51%) 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/prepare_build/action.yml b/.github/actions/get_deps/action.yml similarity index 51% rename from .github/actions/prepare_build/action.yml rename to .github/actions/get_deps/action.yml index 5f2c544c1..38b44a70e 100644 --- a/.github/actions/prepare_build/action.yml +++ b/.github/actions/get_deps/action.yml @@ -1,30 +1,29 @@ -name: Prepare to build +name: Get dependencies inputs: - family: + arg: 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') + 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: Get Dependencies + - name: Linux dependencies + if: runner.os == 'Linux' 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 + + - 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/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) From 4cecb759c9cc5854a12380814bc49a8efddcea3c Mon Sep 17 00:00:00 2001 From: Rbb666 Date: Sat, 11 May 2024 16:47:15 +0800 Subject: [PATCH 454/454] [osal]add usb host script. --- lib/rt-thread/SConscript | 54 +++++++++++++--------- lib/rt-thread/tusb_config.h | 71 +++++++++++++++++++++++++++++ lib/rt-thread/tusb_rt_thread_port.c | 5 ++ 3 files changed, 109 insertions(+), 21 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,33 +5,45 @@ 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"] - -if GetDepend(["PKG_TINYUSB_DEVICE_MSC"]): - src += ["../../src/class/msc/msc_device.c", "port/msc_device_port.c"] - LOCAL_CFLAGS = '' +# 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"] + + if rtconfig.PLATFORM == 'gcc' or rtconfig.PLATFORM == 'armclang': # GCC or Keil AC6 LOCAL_CFLAGS += ' -std=c99' elif rtconfig.PLATFORM == 'armcc': # Keil AC5 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 } }