felis / USB_Host_Shield_2.0

Revision 2.0 of USB Host Library for Arduino.
https://chome.nerpa.tech
1.8k stars 780 forks source link

SPI CS pin configuration on STM32 nucleo-f446re #605

Closed MasterJubei closed 3 years ago

MasterJubei commented 3 years ago

https://github.com/Lauszus/Nucleo_F446RE_USBHost I read the readme for the usb host shield and it says the F446RE is supported with that. However it does not work for me. Maybe it works with the mini usb host shield he mentions, but I don't see why that would make a difference.

From the ICSP connector on the usb host shield 2.0 I can connect MISO,MOSI, etc to the nucleo board with male to male wires without a problem. However the issue is the CS. There is no CS pin defined in his code as far as I can tell. https://github.com/Lauszus/Nucleo_F446RE_USBHost/blob/master/466_USBHost/Src/main.cpp

I tested the host shield on an arduino uno, I connected the ICSP wires to each other, power, and CS, and left INT and GPX disconnected. The USB dongle works fine, it can happily pair.

If I disconnect CS from the arduino, I can no longer pair with the USB BT dongle.

How can I configure the CS pin on stm32 to work? Also when compiling,

warning "You need to initialize the SPI interface manually when using the STM32F4 platform"

This is true ;p, but I am having issues with this mixture of Arduino and STM code.

Also if anyone is nice enough to try and compile this, just use stm32cubeide instead of system workbench. The project imports fine with stm32cubeide and there is no real configuration needed.

Lauszus commented 3 years ago

The CS is pin 10 and the INT is pin 9. Please see: https://github.com/felis/USB_Host_Shield_2.0#interface-modifications.

You need to connect both SS and INT. It is okay to leave GPX disconnected.

Be careful using the full size shield if the pins on your microcontroller are not 5V tolerant, as the shield features logic level shifters that converts the 3.3V signals of the MAX3421E into 5V.

MasterJubei commented 3 years ago

The CS is pin 10 and the INT is pin 9. Please see: https://github.com/felis/USB_Host_Shield_2.0#interface-modifications.

You need to connect both SS and INT. It is okay to leave GPX disconnected.

Be careful using the full size shield if the pins on your microcontroller are not 5V tolerant, as the shield features logic level shifters that converts the 3.3V signals of the MAX3421E into 5V.

Thanks for replying all the emails btw ;D I have pin 10 on the nucleo connected to SS on the usb host shield, and pin 9 is connected to INT

However in the output I get 'OSC did not start' I am using your code verbatim on a new project, besides uncommenting the pair mode line PS4BT PS4(&Btd, PAIR);

I see the pin declarations in UsbCore.h, but does that mean we do not have to declare a CS and INT in cubemx/in our main? I am not sure if all the library functions of arduino work.

Lauszus commented 3 years ago

The only thing you need to do is to enable the SPI interface you want to use similar to how I did it: https://github.com/Lauszus/Nucleo_F446RE_USBHost/blob/master/466_USBHost/Src/main.cpp#L201-L215 and make sure the clocks are enabled for the GPIO pins you want to use: https://github.com/Lauszus/Nucleo_F446RE_USBHost/blob/master/466_USBHost/Src/main.cpp#L231-L237.

The USB Host Shield library will take care of setting up the SS and INT pins here: https://github.com/felis/USB_Host_Shield_2.0/blob/master/usbhost.h#L428-L431 by using the STM32 HAL library: https://github.com/felis/USB_Host_Shield_2.0/blob/master/avrpins.h#L1247-L1270, so you do NOT need to that manually.

And here are the pin definitions based on the NUCLEO-F446RE board: https://github.com/felis/USB_Host_Shield_2.0/blob/master/avrpins.h#L1273-L1293 i.e. SS is using GPIOB6 and INT is using GPIOC7.

bobbatcomcastdotnet commented 3 years ago

RailRanger,

I implemented the USB Host Library into a project using an STM32H743 chip (using a proprietary IDE) and after some startup issues everything is working just fine. I am using a clone mini shield but you are correct in assuming that the full shield should work okay. If you are using a clone be careful to observe the shield setup so that the signals are not level shifted to 5V. In addition make sure that 'STM32F446xx' is defined in the project so the pin-definitions in avrpins.h are included correctly.

MasterJubei commented 3 years ago

Thank you both for the replies!

I am using a clone as well, I could buy the official one without a problem, but considering I have two clones and they both work fine on the arduino, I think they are not the issue. I had to bridge the vbus power connection, and the 3.3 and 5v connections on the side. I will have to do some reading on the signals being shifted, but if the board works with the arduino it should be okay here too no?

Looking at the code you mentioned Lauszus here https://github.com/felis/USB_Host_Shield_2.0/blob/master/avrpins.h#L1273-L1293 it seems like it should work. I compared the pins to what I have plugged in

I have also tried plugging the usb host shield directly into the nucleo board, but I don't think that will work since the spi pins probably are not configured to look there(I have not checked the code for that yet). I do not get the OSC did not start error if I do that, just Bluetooth library has started, but I also get Bluetooth library has started if nothing is plugged in at all. Pairing does not work.

This is how I have it hooked it up using the ICSP pins, if anything glaring is standing out, please let me know, but don't go wasting your time trying to look at each wire. The breadboard is to split the 5v power since it goes to the ICSP connector and the usb host shield's 5v input.

Also I tried system workbench again instead of stm32cubeide, and this occurs after I run. I am not sure if is a problem. I still get the output 'OSC did not start'. It seems to complain but flashes anyway as far as I can tell. I think this is a conflict with stm32cubeide, but I don't think this has anything to do with the errors with the usb host shield.

Open On-Chip Debugger 0.10.0+dev-00021-g524e8c8 (2019-04-12-08:48)
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
srst_only separate srst_nogate srst_open_drain connect_assert_srst
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
adapter speed: 8000 kHz
adapter_nsrst_delay: 100
Info : clock speed 8000 kHz
Info : STLINK v2.1 JTAG v37 API v2 M26 VID 0x0483 PID 0x374B
Info : using stlink api v2
Info : Target voltage: 3.244649
Info : Unable to match requested speed 8000 kHz, using 4000 kHz
Info : Stlink adapter speed set to 4000 kHz
Info : STM32F446RETx.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : Listening on port 3333 for gdb connections
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x08009f8c msp: 0x20020000
configuring PLL
Info : Unable to match requested speed 8000 kHz, using 4000 kHz
Info : Stlink adapter speed set to 4000 kHz
Info : Unable to match requested speed 8000 kHz, using 4000 kHz
adapter speed: 4000 kHz
** Programming Started **
auto erase enabled
Info : device id = 0x10006421
Info : flash size = 512kbytes
target halted due to breakpoint, current mode: Thread 
xPSR: 0x61000000 pc: 0x20000046 msp: 0x20020000
wrote 131072 bytes from file Debug/466_USBHost_Configuration.elf in 4.263995s (30.019 KiB/s)
** Programming Finished **
** Verify Started **
target halted due to breakpoint, current mode: Thread 
xPSR: 0x61000000 pc: 0x2000002e msp: 0x20020000
verified 73972 bytes in 1.150977s (62.763 KiB/s)
** Verified OK **
** Resetting Target **
shutdown command invoked

21-02-22 18-33-50 0168 21-02-22 18-33-29 0165

bobbatcomcastdotnet commented 3 years ago

Do you have the RST signal on the shield tied to the 3V3 rail? The RST signal must not be left floating or spurious resets will occur which can cause the problem you are seeing.

MasterJubei commented 3 years ago

Yeah I have tried connecting the RST on the ICSP connector on the shield connected to both the nucleo's NRST and the 3.3V just now and I still get 'OSC did not start'.

I also tried an ESP32 and I also get 'OSC did not start'. For wiring the esp32 I connected 5v from the nucleo to the ICSP vcc and the 5v on the side which is bridged to the vbus. This is just because the esp32 dev board has no 5v rail. I probably did not(and should not) need to connect 5v on the VCC on the ICSP.

Both usb host shields still work just fine with the arduino uno. I am not wiring the ICSP backwards either.

For the arduino uno, it outputs 5v at both the RST pin and VCC on the ICSP connector.

So with that for the nucleo, I also tried connecting the RST from the usb host shield to 5v, and same for VCC. It made no difference. Still get the same error.

EDIT: Also the Arduino uno works fine with VCC disconnected and using 3.3V for RST on the ICSP instead of 5v.

bobbatcomcastdotnet commented 3 years ago

Have you tried obtaining a schematic for your USB host shield from whomever manufactured it?

MasterJubei commented 3 years ago

I am using this https://www.amazon.com/ARCELI-Shield-Arduino-Support-Android/product-reviews/B07J2KKGZ4/ref=cm_cr_dp_d_show_all_btm?ie=UTF8&reviewerType=all_reviews

I will see if they have one, although it looks the same. In the meantime I could try picking up the mini variant since that one is more simple. Although if that works I will still want to see what is going wrong here.

MasterJubei commented 3 years ago

aaaaaaaaaaa I got it!

https://github.com/Lauszus/Nucleo_F446RE_USBHost/blob/master/466_USBHost/Src/main.cpp#L209

This was too aggressive, I had to use a prescaler of 16 So with it changed to SPI_Handle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;

It works!

Thank you both!

Working wiring configuration I am using is:

Nucleo USB_Host_shield
D10 SS
D9 INT
   
D11 ICSP MOSI
D12 ICSP MISO
D13 ICSP SCK
not connected ICSP VCC
3.3V ICSP RST
   
5v 5V input under reset button
3.3V 3.3V input under reset button

Reference image of ICSP for anyone else who finds this thread

d593600bb7b1cd07e141c122db083c03

bobbatcomcastdotnet commented 3 years ago

I'm happy you found the problem :)

Lauszus commented 3 years ago

@RailRanger good to hear and thanks for sharing, so other people can find it when they google for it :)

MasterJubei commented 3 years ago

@Lauszus Thanks that means a lot!

Sorry to bother you again and this is slightly off topic, but why have you changed the interrupt speed to every us? If I use the default 1ms, it does not work. Are you polling the 3421e at 1mhz? I would like to play around with freertos, and I am pretty sure having the systick at that speed will cause issues. https://github.com/Lauszus/Nucleo_F446RE_USBHost/blob/master/466_USBHost/Src/main.cpp#L193

I am looking at usbhost.h and I am guessing it is for the interrupt to the max3421e. Is there a way to get this running while keeping systick running at 1ms?

bobbatcomcastdotnet commented 3 years ago

Hi RailRanger,

I asked the same question when I was working on the H743 implementation. The response was:

I think I did it, so the following function would just work: https://github.com/Lauszus/Nucleo_F446RE_USBHost/blob/master/Arduino_libs/Arduino.h#L16-L19.

A better way is to like I did for another project. In that code I set up the timer to interrupt every 1 ms: https://github.com/UltimateHackingKeyboard/firmware/blob/a7ce25682defad8fdc66e19151a0d8c5fd679826/right/src/timer.h and then incremented a counter in the interrupt: https://github.com/UltimateHackingKeyboard/firmware/blob/a7ce25682defad8fdc66e19151a0d8c5fd679826/right/src/timer.c#L11, then you simply convert the current timer count to us and then add that to the ms counter: https://github.com/UltimateHackingKeyboard/firmware/blob/a7ce25682defad8fdc66e19151a0d8c5fd679826/right/src/timer.c#L32-L42 in the micros function

I removed the us setup for systick and ran it at 1ms and I removed the print code and everything worked just fine.

I hope this helps ;)

Regard, Bob Bertram

MasterJubei commented 3 years ago

@bobbatcomcastdotnet Thanks a lot, that's extremely useful.

EDIT: Based on your findings, Thanks for listing Arduino.h! For now I just changed Arduino.h to:

#ifndef __arduino_h__
#define __arduino_h__

#include <math.h>
#include "Print.h"
#include "Stream.h"

#include "SerialClass.h" // Arduino style Serial class

#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))

#define PI M_PI
#define RAD_TO_DEG (180.0 / M_PI)

#define delay(ms) HAL_Delay(ms)
#define delayMicroseconds(us) HAL_Delay(us*1000)
#define millis() (HAL_GetTick() / 1)
#define micros() HAL_GetTick()*1000

#endif

Works great. You are right your implementation is definitely better using a separate timer. I will do the same shortly.

xxxajk commented 3 years ago

I've got to love how all the clones are revision 2.0.0 which totally lack the power control.

MasterJubei commented 3 years ago

The issue in this original post has been long since solved but I just wanted to share this since this was what I was working on ;p https://github.com/MasterJubei/OGX_STM32 I managed to get the PS4 wireless controller working on the original XBOX with this setup. Might be useful for anyone else who attempts also tries to use the USB host shield libraries with the ST ones. Wouldn't have been able to do it without the help here.

Lauszus commented 3 years ago

@MasterJubei cool project :)

I've been thinking about adding a FreeRTOS example, as then people do not have to worry about not blocking the loop and the USB Host code won't block the MCU for doing other stuff with higher priority that needs to run at more often than every 1 ms.

xxxajk commented 3 years ago

Or, you could just use UHS3, not worry about having to use an RTOS at all. UHS3 needs a little bit of help as well. There's some things that are still acting up, and I've been so busy with production of hardware here, that I have no time currently. There's only 2 things that you would have to do to port it to UHS3: 1: If using the shield, there's nothing to add except stealing a hardware IRQ that your project doesn't use. The library is CMSIS aware, and uses newlib hooks to make heap ISR safe. Most newlib installations should work out of the box. 2: If you are using a native USB on st, port the SEI in addition to number 1.

Most things should work correctly as long as you do not use a hub, which is currently unverified, and needs some extra work. Most of the issues I have found with UHS3 have been involving the fact that UHS3 is more sensitive to poor power designs and poor interference mitigation, and since it is using an interrupt, it is more sensitive. If the target chip offers digital filtering, then you won't have as many problems. I know that Freescale ARM devices have the digital filters, but unfamiliar with st's offerings.

xxxajk commented 3 years ago

@MasterJubei cool project :)

I've been thinking about adding a FreeRTOS example, as then people do not have to worry about not blocking the loop and the USB Host code won't block the MCU for doing other stuff with higher priority that needs to run at more often than every 1 ms.

That's one of the reasons I wrote the XMEM task library, which isn't an RTOS, and it was basically a path finder for UHS3, and how I would have to do UHS3.