Author Topic: STM32 USB libraries  (Read 7746 times)

0 Members and 1 Guest are viewing this topic.

Offline lawrence11Topic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 322
  • Country: ca
Re: STM32 USB libraries
« Reply #25 on: January 25, 2020, 07:39:53 am »
Can anybody share insight onto how people usually debug IRQ's from complicated libraries that elude them?

Cant seem to follow along 100% of the way, am trying hard to setup a Hardware breakpoint somewhere, but where?

 

Offline blacksheeplogic

  • Frequent Contributor
  • **
  • Posts: 532
  • Country: nz
Re: STM32 USB libraries
« Reply #26 on: January 25, 2020, 08:27:52 am »
Can anybody share insight onto how people usually debug IRQ's from complicated libraries that elude them?

Cant seem to follow along 100% of the way, am trying hard to setup a Hardware breakpoint somewhere, but where?

I usually instrument the code path. I find it is often  quicker than stepping in a debugger and it also has minimal run-time impact.
 

Offline lawrence11Topic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 322
  • Country: ca
Re: STM32 USB libraries
« Reply #27 on: January 25, 2020, 03:21:46 pm »
I would like to do that, I will insert a printF in it, once I can find where to put it.

Well my needs right now are educationnal, I managed to make the device class work and move a mouse. But I also wanna learn how to use big libraries, explore them to see how the registers are setup, btw I hate big libraries.

I thought a Hardware breakpoint had superpowers and can never be skipped by an interrupt routine and the reason I didnt find the "culprit" yet is because I havent put the Hardware bp in the right function yet.
« Last Edit: January 25, 2020, 04:00:08 pm by lawrence11 »
 

Offline lawrence11Topic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 322
  • Country: ca
Re: STM32 USB libraries
« Reply #28 on: January 25, 2020, 04:19:34 pm »
Also, the ogden was partly right.

3 or 4 of these registers react and stop on the line once commanded by a C/C++ Watchpoint.

Wich is a useful trick.

But most of them are only discovered as "murdered", it seems as if this is a "priority game" and that the Debuggers priority  is unable to stop this IRQ (the silent invisible register setter), or w/e name it should have.

Now I guess blacksheeplogic is right, when you debug these high priority IRQ's ( Or should I say low in cortex-M terms), instrumentation by SWO should be the standard debug tactic, wich incurs being in control and knowing where to put it.

Sadly I remain in the dark as to the mysteries of these ST Libraries, I'm the little cuckold of these libraries, and I dont like this.
« Last Edit: January 25, 2020, 04:23:35 pm by lawrence11 »
 

Offline lawrence11Topic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 322
  • Country: ca
Re: STM32 USB libraries
« Reply #29 on: January 25, 2020, 06:18:28 pm »
So I guess I should just treat it as such? A black box and send report?

Forget about all this, stick to the descriptors as in the videos.
 

Offline ogden

  • Super Contributor
  • ***
  • Posts: 3731
  • Country: lv
Re: STM32 USB libraries
« Reply #30 on: January 25, 2020, 06:58:16 pm »
I havent put the Hardware bp in the right function yet.
"In the function" is code breakpoint, not data or IO memory access breakpoint.
 

Offline lawrence11Topic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 322
  • Country: ca
Re: STM32 USB libraries
« Reply #31 on: January 25, 2020, 08:02:41 pm »
I havent put the Hardware bp "On the right function" then, right on the line name. A blue dot with Hardware type?  :-//

Anyways, Address watchpoint, or SFR watchpoint, w/e you wanna call it, is late on the ball on certain address while others work OK.

Its a Watchpoint that can stop the execution on the right line, when the conditions are right, yes, quit useful, but not in this case.

Super man come, superman steals the bank, I blink and see nothing.

Why is that?  :-//  See my theory above.

Maybe I'm stupid I dunno, I dont know how to do this "data or IO memory access breakpoint." that catches this culprit. I use STM32CUBEIDE remember.
« Last Edit: January 25, 2020, 08:13:39 pm by lawrence11 »
 

Offline LostTime77

  • Contributor
  • !
  • Posts: 13
  • Country: us
Re: STM32 USB libraries
« Reply #32 on: March 03, 2020, 04:23:28 am »
Ah the infamous Synopsys USB IP. I have developed many a bare metal USB driver for my previous company for the STM32 controllers. The STM32 have several forms of IP used for the USB controllers in the chips. The main two are the synopsys IP, which I can tell just by looking at those registers and a device only IP. The device only IP is much easier to work with compared to the synopsys IP, which supports OTG. Fun fact - many people from the raspberry pi side have still not figured out that the IP for the USB module inside the pi is identical to the STM32 Synopsys IP (they use the same IP). Register sets are identical.

Anyhow, let me be frank and say you will not get very far in trying to hit breakpoints and having useful information be produced from the USB registers. The reason is that the synopsys IP works a lot in the background without being knowledgeable of what you are trying to do in the debugger. For example, you could set a breakpoint for an interrupt after a packet is sent and expect certain bit patterns inside the USB registers in that interrupt only to find those bits are not in the state you expect - the hardware has already done a lot of hand wiping before you can catch it.

For debugging the USB hardware, the easiest solution is to do it at higher level in the drivers - not looking at individual bits in the registers but instead looking at overall transactions. Even trying to write debugging code to save the states of registers before your debugger breakpoints hit is not very reliable due to the previous paragraph. Part of the why this happens is because of the two complicated clock domains and clock crossings between the CPU and USB hardware. My advice would be to scour the documentation closely and understand what it is doing at a high level and how the register bits play a role in that. From this you can understand better what is happening and or design your own code / tests to make the hardware work. Another fun fact - I have cross referenced some documentation with the EFM32 USB peripheral a lot, because it contains the EXACT same synopsys USB IP as well.

The way the hardware works is a little convoluted; however, also being an FPGA / hardware developer myself, I can understand the design decisions. Once you figure it out and compare to what they 'could' have done you will find its not the worst way of doing things.

The Synopsys OTG IP can be found on any STM32 that has the OTG functionality and the device only USB IP can be found in some STM32 chips with lessened functionality (STM32L5, some STM32L4, some of the old STM32F series). The device only IP is 'much' easier to work with even if it requires a bit more hand holding in software, but doesn't require you to sacrifice an arm and a leg to understand exactly what its doing compared to the synopsys IP.
« Last Edit: March 03, 2020, 04:36:59 am by LostTime77 »
 
The following users thanked this post: Dielectric, Silenos

Offline andersm

  • Super Contributor
  • ***
  • Posts: 1198
  • Country: fi
Re: STM32 USB libraries
« Reply #33 on: March 03, 2020, 06:57:58 am »
Fun fact - many people from the raspberry pi side have still not figured out that the IP for the USB module inside the pi is identical to the STM32 Synopsys IP (they use the same IP). Register sets are identical.
According to Synopsys engineers on the Linux-USB mailing list, there are in fact several versions of the same DWC2 controller, with slightly different capabilities. There's also a number of knobs the silicon vendor can use to tune the controller to their specific application.

Offline lawrence11Topic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 322
  • Country: ca
Re: STM32 USB libraries
« Reply #34 on: March 03, 2020, 02:04:12 pm »
Code: [Select]

uint16_t buffer_k[4];


extern USBD_HandleTypeDef hUsbDeviceHS;

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USB_DEVICE_Init();
  MX_SPI1_Init();
  MX_SPI2_Init();
  MX_SPI3_Init();
  MX_TIM2_Init();
  /* USER CODE BEGIN 2 */
  buffer_k[0]=0b0000000000000001;//reportID
  buffer_k[1]=0x0400;//modifier
  buffer_k[2]=0;//OEM
  buffer_k[3]=0;//keycode data


  LL_SPI_Enable(SPI2);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {

HAL_Delay(100);
USBD_HID_SendReport(&hUsbDeviceHS, (uint8_t *)buffer_k, sizeof(buffer_k));


 

  }
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */

  /* USER CODE END 3 */
}

Why doesnt this code write A ??  it does when I go by the example.
 

Offline LostTime77

  • Contributor
  • !
  • Posts: 13
  • Country: us
Re: STM32 USB libraries
« Reply #35 on: March 03, 2020, 04:11:25 pm »
Fun fact - many people from the raspberry pi side have still not figured out that the IP for the USB module inside the pi is identical to the STM32 Synopsys IP (they use the same IP). Register sets are identical.
According to Synopsys engineers on the Linux-USB mailing list, there are in fact several versions of the same DWC2 controller, with slightly different capabilities. There's also a number of knobs the silicon vendor can use to tune the controller to their specific application.

The overall operation is the same. The things that I have seen that are silicon options are the number of endpoints, DMA capability, amount of RAM, etc.. How you program transfers in the firmware does (should) not change - its a matter of which endpoint you are using and if its DMA based. Case and point - STM32L4 does not have DMA and has less RAM (IIRC) than a STM32H7 which has DMA and more RAM.

For example, the way the controller handles the receive FIFO in terms of the information words that the controller puts there should not change (packet complete, setup packet received, NAK received, etc.). This is really the bulk of the understanding of how the controller works and causes the most confusion. If there is a different way to load and start packet transfers between controllers, it doesn't matter so much; understanding the overall hardware flow is the toughest nut to crack.

Compare this with the device only IP that essentially you hand hold on 'every' packet transfer inside the firmware. Theres a 'lot' less unknowns about what is going on.
« Last Edit: March 03, 2020, 04:16:34 pm by LostTime77 »
 

Offline lawrence11Topic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 322
  • Country: ca
Re: STM32 USB libraries
« Reply #36 on: March 03, 2020, 04:26:41 pm »
Nah sorry, theres something that messes up the descriptor and now it has the same icon but is a mouse

sorry guys.

I upgraded cubemx and it did a stealth change somewhere and I was only checking the control panel and it looked the same, but it was not the same.

weird shit, I sware I didnt touch cubemx.

back to square 1, from like 10 days ago.
 

Offline lawrence11Topic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 322
  • Country: ca
Re: STM32 USB libraries
« Reply #37 on: March 03, 2020, 06:18:55 pm »
Code: [Select]
  while (1)
#include "usbd_hid.h"
#include "usbd_customhid.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
SPI_HandleTypeDef hspi2;

/* USER CODE BEGIN PV */
uint16_t bufferk[6];
int *ptr; // so whats the magic here that I gotta do to start at bufferk+2




extern USBD_HandleTypeDef hUsbDeviceHS;
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_SPI2_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */
 

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USB_DEVICE_Init();
  MX_SPI2_Init();
  /* USER CODE BEGIN 2 */

  bufferk[0]=0;
  bufferk[1]=0;
  bufferk[2]=1;//reportID
  bufferk[3]=0x0400;//modifier
  bufferk[4]=0;//OEM
  bufferk[5]=0;//keycode data



  /* USER CODE END 2 */
 
 

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {


  USBD_HID_SendReport(&hUsbDeviceHS, (uint8_t *)bufferk[2], 8); //gives warning, dont type A
  HAL_Delay(100);
  USBD_HID_SendReport(&hUsbDeviceHS, (uint8_t *)bufferk[2], 8); //gives warning, dont type A
  HAL_Delay(100);
  USBD_HID_SendReport(&hUsbDeviceHS, (uint8_t *)bufferk[2], 8); //gives warning, dont type A
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
  }

Now whats the best way to pass an offset array?

If I make it like this, it writes A, gives no warning

uint16_t bufferk[4];

  bufferk[0]=1;//reportID
  bufferk[1]=0x0400;//modifier
  bufferk[2]=0;//OEM
  bufferk[3]=0;//keycode data

USBD_HID_SendReport(&hUsbDeviceHS, (uint8_t *)bufferk,8 );
« Last Edit: March 03, 2020, 06:21:11 pm by lawrence11 »
 

Offline rounin

  • Regular Contributor
  • *
  • Posts: 128
  • Country: us
Re: STM32 USB libraries
« Reply #38 on: March 03, 2020, 07:30:03 pm »
Can anybody share insight onto how people usually debug IRQ's from complicated libraries that elude them?

For ISRs that can tolerate some small delay I have a logging framework that uses an object pool for string buffers. It is safe to try_allocate strings from the ISR and seems to be fast enough. This lets you log up to however many strings are in the object pool with minimal overhead.

I actually used this while writing my USB driver for the STM32H7. I had a lot of logs queue inside the interrupt (logging silicon IP state & bus traffic), still was able to enumerate and service USB HS. Another thread (FreeRTOS) sends the logs out the UART when there isn't anything else to do.

So to generalize for another lib, I have added code to the vendor libs to log stuff. Sometimes just dropping the IP state in a queue.
« Last Edit: March 03, 2020, 07:32:04 pm by rounin »
 

Offline lawrence11Topic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 322
  • Country: ca
Re: STM32 USB libraries
« Reply #39 on: March 03, 2020, 07:54:16 pm »
Bah, All that stuff is old.

I dont really care anymore, peoplse seem to hack things together by molding the black box to their needs.

My question now, how to write A as asked above.

I can already write A, but I wanna practice my C.
 

Offline LostTime77

  • Contributor
  • !
  • Posts: 13
  • Country: us
Re: STM32 USB libraries
« Reply #40 on: March 03, 2020, 09:14:35 pm »
Sorry.. I will be honest.. I have not been reading every nook and kranny on this thread. What was the actual question?

Are you asking why something like this:

USBD_HID_SendReport(&hUsbDeviceHS, (uint8_t *)bufferk[2], 8); //gives warning, dont type A

Is giving you a warning? You asked how do you "write an offset array"? I am not sure what that means, but I think you are asking how do you pass a pointer to the array from a given offset. I have not looked at the USBD_HID_SendReport function, but I presume the second parameter is asking for a byte pointer and then parameter 3 is the number of bytes to transfer from the actual data.

What you are doing in the above function call is taking the value of the data at array entry 3 (0 based) and passing that to the function. The type of the value stored in the array is a uint16_t (2 byte data), not a pointer that the function expects. (You can cast a value to a pointer if the value was an actual physical address here, but I don't think that's your intended operation)

I think you want to to pass the data to the function starting at array entry 3. Therefore, the second parameter should be (uint8_t*)&bufferk[2]. The third parameter should be 8 or less since there are only 8 bytes of data starting at array entry 3 (your array is 6 entries big).

ALSO! It looks like you are trying to manipulate multi byte data values in a buffer that is transferred byte wise on the USB bus. Keep in mind that in USB the endianness does matter. If you wanted the code to be portable, the usual way is to declare a byte buffer and have a function to be called to encode each multi byte data value into that buffer with the correct endianness. This buffer is then encoded properly as per whatever your USB class is to be sent as raw bytes to the driver. For low level testing and fast stuff, I don't think there is an issue with what you have done, but keep in mind that the uint16_t data values going into your buffer may not be in the correct endianness that the HID class expects. (Talking general terms here... take note.. HID might already be little endian.. would have to look it up)
« Last Edit: March 03, 2020, 09:26:13 pm by LostTime77 »
 

Offline lawrence11Topic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 322
  • Country: ca
Re: STM32 USB libraries
« Reply #41 on: March 03, 2020, 09:51:51 pm »
awesome bro thx it works, writing A.

&buffer[2]

& = the address of.

Since an array is already a pointer it can be already written & if I want to.
 

Offline Kilrah

  • Supporter
  • ****
  • Posts: 1852
  • Country: ch
Re: STM32 USB libraries
« Reply #42 on: March 03, 2020, 10:11:41 pm »
Why are you making an array of uint16_t instead of uint8_t like in the example?
These things work on bytes so you're only making your life harder and risking to cause you all sorts of trouble.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf