STM32F103: ADC hardware fault or code issues - Page 1
Forum section: electronics / general

author: uer166
author_rank: Super Contributor
timestamp: August 12, 2018, 07:50:40 am
content: Recently spent a few days hacking/reverse engineering a Xiaomi M365 scooter, decided to write own FW for motor controller that's based on a STM32F103C8T6. New to STM32, it's an uphill battle, especially with unfriendly dev tools, but so far I was able to remove readout protection, flash own FW that blinks LED on board, debug, change clocks, etc..First thing to do is get ADC feedback from the BLDC shunt current monitors, the voltage at 0A phase current sits at 1.65V on pins 13,14,15, so ADC value should be non-zero. Issue is, no matter how hard I try, value returned byADC is always 0(seeing this by inspecting the result variable in debugger). I tried internal temp sensor as well to isolate GPIO setup issues, same thing. I'm using polled ADC, but the idea is to use DMA on all 3 channels, as well as the analog watchdog to handle overcurrent events and cycle-by-cycle current limit.Attached is the source which pretty much has everything except boilerplate System Workbench generated files. As much as I tried to avoid, HAL is used for everything.The reason original FW wasn't working is because it was throwing a code, that according to some russian hackers meant issues with shunt calibrations, self-test failure, etc. I probed all the hardware on the board, and compared feedback to MCU with a working unit, and they were all exactly the same, down to the startup self-test waveforms. Now I'm thinking ADC is somehow blown up, but can't confirm, since don't have another STM32 to play with.TL/DR: noob that can't use STM32 ADCAnyone can take a look, for obv. mistakes? Also, does any self-test code exist for ADC peripheral a. la IEC 60730?Some relevant parts of the code:Code:void setup_adc(){...ADC_ChannelConfTypeDef ADC_ChannelStruct;HAL_NVIC_SetPriority(ADC1_IRQn, 0, 0);HAL_NVIC_EnableIRQ(ADC1_IRQn);ADC_HandleStruct.Instance = ADC1;ADC_HandleStruct.Init.ContinuousConvMode = ENABLE;ADC_HandleStruct.Init.DiscontinuousConvMode = DISABLE;ADC_HandleStruct.Init.DataAlign = ADC_DATAALIGN_RIGHT;ADC_HandleStruct.Init.ExternalTrigConv = ADC_SOFTWARE_START;ADC_HandleStruct.Init.NbrOfConversion = 1;ADC_HandleStruct.Init.ScanConvMode = DISABLE;if(HAL_ADC_Init(&ADC_HandleStruct) != HAL_OK){asm("bkpt 255");}ADC_ChannelStruct.Channel = ADC_CHANNEL_16;ADC_ChannelStruct.Rank = ADC_REGULAR_RANK_1;ADC_ChannelStruct.SamplingTime = ADC_SAMPLETIME_13CYCLES_5;if(HAL_ADC_ConfigChannel(&ADC_HandleStruct, &ADC_ChannelStruct) != HAL_OK){asm("bkpt 255");}}int main(void){HAL_Init();enable_clocks();setup_led();setup_clocks();setup_adc();led_off();while(1){// ADC measurment & display valueHAL_ADC_Start(&ADC_HandleStruct);HAL_ADC_PollForConversion(&ADC_HandleStruct, 1000); // 1000 is timeout in milisecondsADC_val = HAL_ADC_GetValue(&ADC_HandleStruct);HAL_ADC_Stop(&ADC_HandleStruct);}}

author: JS
author_rank: Frequent Contributor
timestamp: August 12, 2018, 09:10:42 am
content: Stm is a bitch till ypu get the hang off, use a demo bpard and experiment with cube, if you will esd about free rtos and make things easier.JS

author: langwadt
author_rank: Super Contributor
timestamp: August 12, 2018, 11:15:24 am
content: find another board with a STM32F103 on it?

author: mbless
author_rank: Regular Contributor
timestamp: August 12, 2018, 04:25:28 pm
content: What channel are you putting for pins 13, 14, and 15? In the code you provided you have channel 16, but that MCU only has ADC channels up to 9...

author: uer166
author_rank: Super Contributor
timestamp: August 12, 2018, 05:51:19 pm
content: I used ADC channels 3,4,5 for pins 13,14,15. The channel 16 is the internal temp. sensor I was trying to read. And yes, the smart way would be to find another board, but can't do that within the weekend..

author: DannyTheGhost
author_rank: Contributor
timestamp: August 12, 2018, 06:18:37 pm
content: The only thing i can suggest you is to use some debugging tool to check ADC registers. It may be the issue when ADC peripheral was simply not turned on.

author: uer166
author_rank: Super Contributor
timestamp: August 23, 2018, 01:24:00 am
content: So I wasn't insane, tried dev board, and lo and behold, existing code outputted correct ADC values. Swapped MCU from dev board into the motor controller, and everything worked as well. I've never seen a chip's ADC be blown, while the rest of the MCU seems to work normally.

author: trevmar
author_rank: Newbie
timestamp: November 06, 2018, 04:38:44 am
content: Quote from: uer166 on August 12, 2018, 07:50:40 amThere have been several discussions here postulating whether, or not, it is possible to disable Read Data Protection in the STM32F103 without losing the data in Flash, yet it seems you have been able to achieve this. Can you give us some idea of how you did it?

author: Rasz
author_rank: Super Contributor
timestamp: November 06, 2018, 06:55:46 pm
content: Quote from: uer166 on August 12, 2018, 07:50:40 amgood RE target considering those are free thanks to Bird/Spin/Blue DuckQuote from: uer166 on August 12, 2018, 07:50:40 amcare to share the method?

author: DannyTheGhost
author_rank: Contributor
timestamp: November 06, 2018, 08:00:30 pm
content: I noticed that when you're trying to use any peripheral with HAL, it requires init function in main(), like HAL_ADC_Init()Maybe that's your problem?

author: uer166
author_rank: Super Contributor
timestamp: November 06, 2018, 09:12:12 pm
content: Never said anything about removing readout protectionwithoutnuking the flash. I removed it, which erased all the contents. From some quick research I don't think anyone found any vulnerabilities on F103 yet.. I'm spending some time developing motor controls code from scratch currently. So far it spins and regens in open-loop mode, but nothing serviceable yet.The ADC init code is correct, it was indeed a blown ADC peripheral as I said earlier.

author: uer166
author_rank: Super Contributor
timestamp: November 06, 2018, 09:13:15 pm
content: Quote from: DannyTheGhost on November 06, 2018, 08:00:30 pmHAL_ADC_Init() is called in my setup_adc function, so all good

author: uer166
author_rank: Super Contributor
timestamp: November 06, 2018, 09:14:56 pm
content: Quote from: Rasz on November 06, 2018, 06:55:46 pmYa know it