Skip to content

Instantly share code, notes, and snippets.

@sidprice
Created January 23, 2020 17:34
Show Gist options
  • Save sidprice/9f6be84582bb02a86b255d8e841f31bb to your computer and use it in GitHub Desktop.
Save sidprice/9f6be84582bb02a86b255d8e841f31bb to your computer and use it in GitHub Desktop.
Problem:
While the USART Rx is working and collects data into a buffer calls to write the data to the trace endpoint are failing. The locm3 function returns zero.
Observations:
"usbd_ep_write_packet" returns a value of zero.
Tracing the above call reveals the locm3 function "dwc_ep_write_packet" is called by the above function and the first test made in that method is causing an immediate return:
uint16_t dwc_ep_write_packet(usbd_device *usbd_dev, uint8_t addr,
const void *buf, uint16_t len)
{
const uint32_t *buf32 = buf;
#if defined(__ARM_ARCH_6M__)
const uint8_t *buf8 = buf;
uint32_t word32;
#endif /* defined(__ARM_ARCH_6M__) */
int i;
addr &= 0x7F;
/* Return if endpoint is already enabled. */
if (REBASE(OTG_DIEPTSIZ(addr)) & OTG_DIEPSIZ0_PKTCNT) {
return 0;
}
The macros "REBASE" and "OTG_DIEPTSIZ" and used to calculate the register address for the packet count and size registers in the hardware peripheral:
#define dev_base_address (usbd_dev->driver->base_address)
#define REBASE(x) MMIO32((x) + (dev_base_address))
The "OTG_DIEPSIZ" macro is similar to all the macros used to access the peripheral hardware:
#define OTG_DIEPTSIZ(x) (0x910 + 0x20*(x))
It expects the "x" value to be such that it represents either an input or output Endpoint index for calculation of the correct register. Example of the "gdb_data_endp":
static const struct usb_endpoint_descriptor gdb_data_endp[] = {{
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = 0x01,
.bmAttributes = USB_ENDPOINT_ATTR_BULK,
.wMaxPacketSize = CDCACM_PACKET_SIZE,
.bInterval = 1,
}, {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = 0x81,
.bmAttributes = USB_ENDPOINT_ATTR_BULK,
.wMaxPacketSize = CDCACM_PACKET_SIZE,
.bInterval = 1,
}};
Note the value of the endpoint address is "0x81". Looking at the above code for "dwt_ep_write_packet" and the macros, the address of the "OTG_DIEPTSIZ" macro is:
(0x910 + 0x20*(1)) == 0x930
This address is, correctly, OTG_DIEPTSIZ 1.
However, if one considers the Trace Endpoint:
static const struct usb_endpoint_descriptor trace_endp[] = {{
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = 0x85,
.bmAttributes = USB_ENDPOINT_ATTR_BULK,
.wMaxPacketSize = 64,
.bInterval = 0,
}};
The address calculation is:
(0x910 + 0x20*(5)) == 0x9B0
This NOT a valid address of a "OTG_DIEPTSIZx" register because there are only a total of four IN endpoints available.
Therefore, the addresses allocated to the BMP endpoints must be chosen so that they represent the index of either an IN or OUT endpoint, i.e. they must be between 0x00 and 0x03, or 0x80 and 0x83.
Mystery -> Why does native BMP trace work with STM32F103, it has the same number of endpoints as the STM32F401 and uses the same address setup:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment