lucysrausch / hoverboard-firmware-hack

New Hoverboard Firmware Hack. Now written from scratch and generally much better.
GNU General Public License v3.0
683 stars 397 forks source link

New motherboard YST-DXT-J20 V4 with "ATERY" AT32F403RCT6 #97

Open cloidnerux opened 5 years ago

cloidnerux commented 5 years ago

Hello,

I bought a hoverboard mainboard off ebay in order to use this firmware, hover on arrival I realized that this mainboard seems to be newer and different to the ones currently used. It features a "AT32F403RCT6" which seems to be a Chinese STM32F103RCT6 clone with faster clock speed, a M4F core, more peripherals, and more RAM. As far as I could see it, it should be possible to compile the current firmware for the new controller. 2019-05-25 11 19 24

Also, it seems to have dedicated gate driver ICs instead of the discrete ones, some of the connectors are different and the layout changed. They also changed the pinout of the SWD connection. I try to reverse engineer the layout as I could not find anything on the internet at the moment.

Does anybody already have any experience with these boards?

p-h-a-i-l commented 5 years ago

Shoutout to @TomTinkering Is that yet another new variant? Or is this similar to your GD F403 board?

TomTinkering commented 5 years ago

That is exactly my board. The AT32F403 chip is (I think) more or less the same as the GD32F403RCT6, which provides a bit more support/documentation. I have made a schematic of the board.

Here are some resources for the GD version of the chip:

And for the AT32F403 chip:

I have just started working on it, but not much time right now. Pretty sure it will not run the firmware directly, but it should not be too hard to port. I will let you know if I make any progress

cloidnerux commented 5 years ago

The GD32 and the AT32 are not exactly the same devices, they have some differences, however the footprint is quite the same and the schematic matches my board.

I try to compile something for the AT32, hopefully it works.

TomTinkering commented 5 years ago

Hmm, for the artery chip I could only find a chinese datasheet/reference manual. Do you have more information? My chinese is not great :P

cloidnerux commented 5 years ago

Some of the stuff is in English and I use the google translator, otherwise, I am also left to guess. If there is some critical stuff I can ask some Chinese friends of mine if they can translate it for me. From the excerpts, I could understand they have a core which achieves 200MHz operation, the GD32 only achieves 168MHz. I am guessing they are indeed different parts. GigaDevices propably has a serial flash, which is glued on the top of the DIE https://zeptobars.com/en/read/GD32F103CBT6-mcm-serial-flash-Giga-Devices The AT32 might have the flash on the same DIE,

Somewhere on the bottom of this site are the standard lib, the files for their dev board and some other stuff: http://www.arterytek.com/html/product/product_AT32F403.jsp

I expect them to be mostly compatible to the STM32 stuff to allow for easier migration, GigaDevices did the same.

Also I asked on reddit if somebody knows these chips, which brought only little insight: https://old.reddit.com/r/AskElectronics/comments/bs0k3n/someone_heard_of_artery_mcus/ https://old.reddit.com/r/embedded/comments/bs7p1z/xpostsomeone_heard_of_artery_mcus/

TomTinkering commented 5 years ago

Ah that library is great, that will probably answer most of my questions. Thanks, and good luck

cloidnerux commented 5 years ago

The hoverboard hack firmware uses the ST HAL, which isn't provided by Atery. So it is necessary to look through the files and see where there are differences that need to be patched... However it seems that only the "low level" functions should be patched to include the differences between the parts?(Not true)

TomTinkering commented 5 years ago

I would start from the 3ADCs_DMA example, get it running, integrate PWM, UART and GPIO and then take all the non hardware related bits from the hoverboard-hack. I don't think you can reuse much hardware related stuff, or at least, it will be easier to start from scratch, using the STM32F103 source as a reference.

Then based on an #ifdef or maybe something fancy like a chip-ID at runtime, it should not be too hard to merge the two projects back together.

cloidnerux commented 5 years ago

Then based on an #ifdef or maybe something fancy like a chip-ID at runtime, it should not be too hard to merge the two projects back together.

Ok.

I searched a bit for information about the gate driver and it seems to be a copy of the IR2108S

I managed to compile the example code with Keil uVision and upload it with a Segger J-Link, so now I just have to port this to the gcc toolchain

cloidnerux commented 5 years ago

It was a bit frustrating to be able to flash the AT32 with jlink, as there is little to no information about everything. At this point I found out, that I need a flash loader as the flash is not directly wirtable through SWD. So this is some code that is loaded into ram, then the PC is set to the start of the code, it gets executed and it can copy/verify blocks of code that is also within the RAM, crazy stuff.

Luckily everything necessary is within the uVision support package from Atery, so theoretically I have everything to try it.

Software side I could get the Buzzer to work with uVision, so using the timers is no problem. There are tons of examples in the StdLib, which should make it somewhat easy to port the firmware. However a lot of bits and registers are named differently, so there will be some work to make it compatible.

cloidnerux commented 5 years ago

I patched the HAl driver to work with the AT32 and could successfully compile it and upload it. I will test it later today. The code is in my repository https://github.com/cloidnerux/hoverboard-firmware-hack

TomTinkering commented 5 years ago

Thanks for posting all the updates here!

EFeru commented 5 years ago

@cloidnerux Nice work! Few questions: At what frequency do you run the AT32? And is the pinout connections the same as for the STM32 boards? I also ordered the AT32 board. By the way, i made a much beter control for the motors. Maybe you can try and see if you like it. I will make a new commit soon with improvements. You can check it in my repository. https://github.com/EmanuelFeru/hoverboard-firmware-hack

cloidnerux commented 5 years ago

Currently, I set 72 MHz to use the same frequency the STM32F103 code does, in case there is some hardcoded frequency dependent stuff.

The pinout is mostly the same. I use the schematic TomTinkering provided, and it seems that the R_MTR_PHB and R_MTR_PHA are swapped and there are no motor current shunts. Also, the LED is missing or is on one of the auxiliary boards.

I had an error in my hardware definition files so my code did not work yesterday, I fixed it but I have to try it today, so hopefully, everything now works as intended and I can test your changes.

EFeru commented 5 years ago

Ok. I am curious if you run it at higher frequency, if you get better performance for the new BLDC control that I made. Just wait for my commit with latest updates. In approx. 2-3 days should be there. I am doing final calibrations and testing.

If no motor current shunts are there, I wonder how do they do the overcurrent protection?

cloidnerux commented 5 years ago

Currently I try to get it working at all. There are a lot of small details that mess up the port.

Maybe later after everything works I try to increase the freqeuncy, however it only helps so much because there is no reason for the MCU to idle for twice the amount of cycles because the control loops are limited by the motor speed.

I think they just measure the phase current and use this value but I really don't know.

cloidnerux commented 5 years ago

Yes! It works now. I ported the HAL libraries, so I hope it is quite easy to use the same code for both MCUs.

EFeru commented 5 years ago

Nice! Let us know the progress.

TomTinkering commented 5 years ago

The board has a simple circuit that trips an IO pin on overcurrent, but not also an amplifier connected to and ADC like the stm32/older boards

EFeru commented 5 years ago

@cloidnerux The new sinusoidal based BLDC control is committed: https://github.com/EmanuelFeru/hoverboard-firmware-hack

Feel free to give it a try...and tell me if you hear the sound of silence :)

cloidnerux commented 5 years ago

I tried it and it works. The motors weren't terrible noisy before, they are not noisy now. They seem to be faster, that could however also be a different setting in the config.h

The wheels seem to "twitch" however in idle. They seem to move a bit forward and backwards.

EFeru commented 5 years ago

At what frequency do you run the controller? You might need to re-adjust the following calibratable in BLDC_controller_data.c :

Recalculate (based on your frequency in Hz)

cf_speedCoef    = round(f_ctrl * 4 * (pi/180) * (30/pi));     % [-] Speed calculation coefficient (factors are due to conversions rpm <-> rad/s) 4 = MechanicalAngle`

Examples: cf_speedCoef = 11111 for f_ctrl ~= 16000 Hz (default) cf_speedCoef = 5333 for f_ctrl = 8000 Hz and so on.

And you might need some adjustmenst on:

dz_counterHi    = 50;       % [-] Counter gradient High. Above this value the control resets to Commudation method (to deal with the high dynamics)
dz_counterLo    = 20;       % [-] Counter gradient Low. Below this value the control authorizes the Advance method (high dynamics have passed)

Then it should be ok. Does it run well (silent) for higher speeds?

cloidnerux commented 5 years ago

I changed the cf_speedCoef to match the control loop frequency and it worked a bit better. However, after some time of idling it starts to twitching again. Is there some I-loop running wild?

EFeru commented 5 years ago

No, it is all open loop and I do not have any Integral action. Is it possible to make a short movie with the behavior?

cloidnerux commented 5 years ago

No, it is all open loop and I do not have any Integral action. Is it possible to make a short movie with the behavior?

I will make a video as soon as I am able to, unfortunately, this will probably be Tuesday.

EFeru commented 5 years ago

@cloidnerux This is how the motors work for me with the code from my main branch (for reference) https://photos.app.goo.gl/E38ZATYqnf8wf9tE6

And comparison with Commutation method (1st half = commutation; 2nd half = Sinusoidal 3rd harmonic) https://drive.google.com/file/d/1vC_kEkp2LE2lAaMCJcmK4z2m3jrPUoBD/view

cloidnerux commented 5 years ago

Here is a video of the old bldc controller: https://youtu.be/Vn0n6_TUgWo

Here is a video of the new bldc controller: https://youtu.be/eXSLYO_MpYY

Here is a video of the wheels jittering while idle: https://youtu.be/7B-F05YvMEU

I think I saw some jittering with the old controller too, however not that strong. I also think that the wheels spin faster with the new bldc controller. The new controller seems to be a bit less noisy, however, I not that much. It might be due to the gate drivers, that there is less switching noise.

EFeru commented 5 years ago

@cloidnerux First of all, very nice setup! I like it... It's very nice, especially with those offroad wheels ;)

Overall, I think it is a good behavior. For me looks improved compared to old method. It does not excite those vibrations (at medium speed) as the old controller does. Currently, I am working on improving even further the dynamic behavior, so stay tuned for an update.

cloidnerux commented 5 years ago

I added a dead band, but it does not help. I don't think it is really a dead band issue, as it only starts after some time stopping. However, it isn't that big of a problem, as it is hardly noticeable during normal operation.

TomTinkering commented 5 years ago

@cloidnerux I finally had some time to work on my own board. Thanks a lot for sharing the port and info on flashing the chip, that saved me a ton of time. Evenything seems to run (interrupt gets executed, buzzer works, I can step through the code), except for the PWM outputs. pwml/r are being set, and the BLCD step returns with values that seem to make sense, but nothing happens on the PWM outputs. I double checked this with a logic analyzer. Have you maybe run into the same problem? Otherwise I will just continue debugging :)

cloidnerux commented 5 years ago

I don't have these problems. The PWM outputs are set, I already drove around with my setup. Is this maybe an issue with the debugging, that some DMA, interrupt or feature is not executed due to the debugging session?

TomTinkering commented 5 years ago

Hmm ok, thanks for the reply. I might have gotten my control wrong, if I set the pwm duty cycles directly they do generate an output, so the driver seems to work. Strange because the CLAMP(...) define should always set a least a minimum duty cycle, and I know that the DMA interrupt is being called since the buzzer works and breakpoints work. Anyway, I will look into it some more tomorrow.

EFeru commented 5 years ago

There is a missalignment on pinout in software (defines.h) vs schematic. sceme Can someone check this? And tell me which one is right.

cloidnerux commented 5 years ago

Depends on what board you have. The older ones have a slightly different schematic to the newer ones/none STM boards. I used the schematic from Tom to setup my defines.h

TomTinkering commented 5 years ago

I guess it depends on how you define left and right. Making the schematic I did not take into account in which direction the wheels would turn "forward" in software. I just named them according to the setup I had in front of me.

In terms of the phases (A/B, B/C, vs U/V), I will double-check this this evening. For the STM32 boards this is indeed the case (different phases are monitored in the the left and right motor). Not so sure about the AT32 board anymore, but I did follow all the traces so the schematic should match that unless I made a mistake.

EFeru commented 5 years ago

Thanks @TomTinkering . Please check the (A/B, B/C, vs U/V) because is important for me that the mapping is correct. Let me know when you have some info.

@cloidnerux , I have an STM32, but I'm interested for both boards, including YST.

marmeladas commented 5 years ago

Hi, have you seen a discussion or guide how to flash AT32 board using ST-Link? I was searching, but no results, everywhere guides for STM32. I think the other option for me is to order J-Link programmer and use cloidnerux's guide to flash the board. But that takes time.

cloidnerux commented 5 years ago

@marmeladas: I don't think there is such a discussion anywhere right now, I could not even find information about the AT32 besides the manufacturers website. However, as the AT32 is very compatible to the stm you might just try to flash it with your st-link and openocd. You might have to create some config files. Another way would be to flash your st-link with "Black Magic Probe" firmware or the "CMSIS-DAP" firmware and try it that way. In the end it is just writing the correct stuff to the correct registers

TomTinkering commented 5 years ago

@EmanuelFeru I went through the schematic for the AT32 board again. There were some naming inconsistencies, which are now fixed. See the updated schematic. (Again, I did not match this with software, I just looked at the board, gave all phases names, named the HALL inputs based on wire color, and all the sense circuits based on which phase they are connected too).

@marmeladas This is just an idea, but it might work if you have an official STLINK-V2 (not the chinese clone). SEGGER has a free utility that updates the ST-Link to a SEGGER compatible device. Pretty sure then you can just follow @cloidnerux instructions. It might be you have to add the AT32 as an STM device, but that's just a matter of placing it in the right folder/section.

@marmeladas Another interesting option might be in this thread, which talks about this firmware for STM32 boards. I have one of those boards, as well an original SEGGER device, and I've tested both succesfully with the AT32 MCU using @cloidnerux instructions

EFeru commented 5 years ago

@TomTinkering thanks a lot. I see that for the RIGHT motor, the current Phases B and C are measured instead of Phase A and B. That is ok, I just needed to be sure. The matching with software I can handle that.

TomTinkering commented 5 years ago

So coding and hardware I can do, but I am not great at motor control. Currently the PWM outputs are working, however, when I set a motor speed, the motor just stalls. I can move it very easily in one direction, and not at all in the other. See this video

I tried all combinations of the settings below: `#define CTRL_TYP_SEL 3 // [-] Control method selection: 0 = Commutation , 1 = Pure Trapezoidal , 2 = Sinusoidal, 3 = Sinusoidal 3rd armonic (default)

define PHASE_ADV_ENA 1 // [-] Phase advance enable parameter: 0 = disabled, 1 = enabled (default)`

@EmanuelFeru Would you know where to start looking? Could this maybe be an issue with the hall sensors, as even Commutation does not work?

cloidnerux commented 5 years ago

@TomTinkering: On my setup I had to switch motor wires. For the left motor I switched yellow and green and on the right motor I connected yellow->green, blue->yellow and green->blue I thought this was an issue with my motors, but it could be a different phase mapping of the controller

EFeru commented 5 years ago

@TomTinkering: You have YST board right? Because my controller is tested on STM32 boards. Could be that the phases are mapped differently on the YST board as @cloidnerux suggested. Usually, that is the behavior you get when phases (or Hall sensors) are mapped differently (I had that when I wrongly connected the phases by mistake).

Regarding, the movie is the link correct? Because I see some soldering video :)

TomTinkering commented 5 years ago

Ah yes, fixed the wrong link. Thanks for the quick reply guys, I will play around with the mapping of the phases this evening. Exciting times :)

TomTinkering commented 5 years ago

Jup, changing a few wires was all it took. Thanks for the help! Video

Just for my understanding: The reason it doesn't work is a wrong mapping between the hall sensors and the phases? For sensor-less control, swapping two phases would only change the direction of the spinning motor right?

If that is the case, I could probably make some sort of calibration function that would auto-detect the correct mapping if you guys think that would be useful.

cloidnerux commented 5 years ago

The reason it doesn't work is a wrong mapping between the hall sensors and the phases? For sensor-less control, swapping two phases would only change the direction of the spinning motor right?

@TomTinkering Yes, thats whats happening. If the phases are mismatched the hall sensors might lag 120° or 240° behind or might rotate in the opposite direction, this trips over the control.

An automatic setup would be nice, however, this would necessitate a parameter storage solution and some other management stuff that is currently not implemented, but could be added. But you should think about how often someone will change his setup and how inconvenient it will be to just switch around the motor cables.

EFeru commented 5 years ago

Nice setup @TomTinkering. Yes, I agree. An automatic detection of wrong Phases connection or Hall sensors would be very useful. You could signal it by activating some buzzer pattern, or if you don't like the buzzer then blink the LED (however, I think the YST board does not have an LED on the mainboard). I am interested how you would achieve that because I don't know how can it be done.

By the way which repo did you use?

TomTinkering commented 5 years ago

I used @cloidnerux fork, as I have the same AT32 board.

As for the detection of the motor, I was thinking something really simple, like a MOTOR_TEST control option that sets both wheels to a low fixed speed, and an array with the 6 possible HALL configurations that the user can try by setting a HALL_CFG_ID define or whatever. This way you should have the wheels turning properly in max six iterations of re-flashing per wheel, without having to change the wiring. Also you don't depend on any external interfaces that might not work (like UART etc.), and if none of the configurations work you know either the board is not compatible, or your hardware setup is not correct.

Maybe this can be improved later by stepping through these configurations automatically, and detecting based on currents/motor speed if the motor is turning properly?

I noticed a much higher current consumption and jerkier movement with wrong wiring, so that should not be too difficult to detect. I was looking at your Simulink model, and although I don't understand all of it, it looks to me like most relevant variables to detect proper operation are already available there (motor speed, phase currents, hall inputs).

EFeru commented 5 years ago

Indeed, some solution would be to just set a constant input (pwm value) and observe the current value (DC current left/right should be sufficient). At the moment, I am not using the current measurement in the Simulink model and BLDC controller. I am investigating the implementation of FOC motor control and then I will use the phase current measurements too. In any case, I think this function to detect the wrong phase connections and correct it in software, should be placed outside the BLDC_controller_step(). I would not put it in the Simulink model because in my opinion this is a low-level diagnostic detection and reaction function. So, I think is should be placed outside the BLDC_controller_step() function.

cloidnerux commented 5 years ago

Well, you could use the Power Button as input. We add a global flag, that the test/setup mode is active and the button is used as the next/store option. Press the button shortly cycles the mapping, pressing it long saves the current state. Then in the test routine the speed is ramped up and down within 5s or so.