## You are here

4 posts / 0 new
javmarina
Offline
Last seen: 2 years 7 months ago
Joined: 2019-10-30 00:13
Posts: 5

I want to customize the VESC firmware for my custom hardware configuration. I have set up most things, but I have issues configuring the ADC vector. Specifically, I don't fully understand the hw_setup_adc_channels() function and the relationship between vector index, pins, ADC device and channels. How can I configure the vector and the pads according to my needs?

I have SENS1...SENS3, CURR1 and CURR2 (2 shunts), EXT for throttle, SIN and COS for encoder (maybe EXT2 and EXT3?), TEMP_MOTOR, TEMP_MOS and AN_IN (Vbus sense).

I also don't fully understanf injected channels and Vrefint.

Teslafly
Offline
Last seen: 1 week 5 days ago
Joined: 2017-09-21 08:55
Posts: 17

so yeah, the adc channels in the firmware are a bit confusing beacuse they need to be set up to continuously sample via DMA.

I recently had to do this with my own hardware so i can probably give some advice.

since you are only using 2 current channels, I'll start with the 4.2 hw.

first in hw_xx.c (hw_40.c used)

you have within hw_init_gpio(void)

	// ADC Pins

palSetPadMode(GPIOC, 5, PAL_MODE_INPUT_ANALOG);

You need to set up all your analog i/o to be input_analog.

If possible when assigning your analog pins, you want to put your phase voltages and current sense on inputs with adc 123, and everything else on the leftovers.

Though in the case of the 4.2hw, the current sensors are on pins with adc 12, which is fine because of the two shunts,

but if you have 3 you really need it to be on adc pins with access to all 3 samplers.

btw, 3 shunts are superior to two if possible and give a better signal quality. Phase shunts are better still because you can filter them as well as double sample in the high and low side.

then in in hw_xx.h, you have (from hw_40.h)

/*
*
* 0:	IN0		SENS3
* 1:	IN1		SENS2
* 2:	IN2		SENS1
* 3:	IN5		CURR2
* 4:	IN6		CURR1
* 5:	IN3		NC
* 6:	VREFINT
* 7:	IN11	NC
* 8:	IN12	AN_IN
* 9:	IN13	NC  (TEMP_MOSFET to make it compile)
* 11:	IN10	TEMP_MOTOR
*/

#define ADC_IND_TEMP_MOTOR		11

The ADC vector comment block is the way to keep your head on straight with all of this.

The first column is the index(vector) of the adc channel in the sampling array. When you use "ADC_Value[adc_ind]", this is the number you are referencing.

The index per input doesn't matter and can move. they just have to match up later.

The second column is the adc pin mux identity. use the schematic to find out which input the pin is.

For example, pin 17 (pa3, ADC123_IN2), is connected to mux input 2,

The third column is the input name. basically match up your schematic signal names to the input mux index and assign them to a incrementing vector number.

HW_ADC_CHANNELS is the number of inputs you have. it is your highest adc vector 11 + 1 (0 indexed), so 12 here.

This determines the size of the adc sampling array.

HW_ADC_INJ_CHANNELS is the number of current sensor channels you have. so 2 for you.

HW_ADC_NBR_CONV is the size of your "blocks" in the next part. In 1,2,3,4.  4 is the max.

The defines following this are just matching the names to the acd index. so all rows of the first and third columns of ADC vector comment block.

The last part is the most confusing.
void hw_setup_adc_channels(void) {

// Injected channels
}

The regular channels are the regularly sampled channels. these are every single analog signal.

They must match up with an adc they are connected to (only a problem for ones connected to adc_12 pins)

Split your channels up into equal sized blocks, make sure that phase voltages and current inputs are split into different blocks.

The blocks must also be of equal size. if you have a smaller block, add an additional current sensor sample at the end. you can see this in the vesc 6 config.

There is no order to the blocks, except that current sensor samples should be first and phase voltage samples second.

next is the structure of :

• ADC_Channel_10 is the the mux IN channel of the pin. (row 2 of adc vector comment block,

in this case it maps to pin 8, PC0(ADC123_IN10), which is PHASE_V_1_ADC)
• 4 is the sample number on that adc converter. it should increase between successive

channel configs for regular, and increase in blocks of simultaneous samples for injected.
• to convert this number to the index defined in "adc indexes", index = ({sample num} -1)*3 + ({adc chan #} -1)
• or refer to the index commments in the code block above. the pattern should be evident.

Injected channels are the current sensors. Since they must be read more frequently, sampling events are injected into the DMA stream.

you need to add all possible combinations of sampling simultaneously.

so in this case channels 5 and 6 are the current sense inputs, sample index 1 measures chan5 with adc2 and chan6 with adc1. index 2 does the inverse.

If possible, use a current limited supply to test your board, and make sure vesc tool values of phase voltage and current in

sampled data are sane if you spin the motor by hand or inject a voltage into one of the phases.

If you are still a bit confused, I recommend looking at the hw 4.2 (HW_40), hw 6, and axiom schematics and hardware configs to see how they differ.

If you come up with modifications for this code but are still having problems getting things to sample correctly, post these 3 blocks of code and your mcu schematic page to the thread and I'll try to find the problem.

javmarina
Offline
Last seen: 2 years 7 months ago
Joined: 2019-10-30 00:13
Posts: 5

Hi Teslafly!

Thank you so much for your detailed explanation. You have helped me a lot.

While I configure the hardware profile, I have some questions to ask. First of all, you said "There is no order to the blocks, except that current sensor samples should be first and phase voltage samples second." but I see that all hardware profiles have SENS (voltage) first and then CURR (current). Maybe you made a mistake there? The same applies to "if you have a smaller block, add an additional current sensor sample at the end. you can see this in the vesc 6 config", aren't they SENS inputs instead?

On the other hand, I have read the STM32F405xx/407xx datasheet and have seen "ADC123" and "ADC12" a lot, as well as in your explanation. I guess those pins are internally connected to the same channel (i.e. multiplexer input) on some ADC drivers simultaneously. Am I right? For example, PC0 has ADC123_IN10, so does that mean that this pin is connected to input 10 of all three multiplexers? Same for ADC12. There aren't pins solely connected to ADC1 or ADC2, right?

The last question is: even though Vrefint is defined and the ADC_Channel_Vrefint is configured in the code, it doesn't seem to be used anywhere, but why?

I'm trying to design the hardware based on the STM32F407 DISCOVERY development board. Not all pins can be used (particularly, PA0 is not available for ADC sampling). For that reason, I'm having a hard time assigning all pins to the analog inputs. I will let you know when more issues arise.

Thank you so much!

EDIT:

I finally did it. This is the code now:

/*
*
* 0:	IN0		SENS1		PA0
* 1:	IN1		SENS2		PA1
* 2:	IN2		SENS3		PA2
* 3:	IN11	CURR1		PC1
* 4:	IN12	CURR2		PC2
* 6:	IN8		ADC_SIN		PB0		// Encoder SIN
* 7:	IN9		ADC_COS		PB1		// Encoder COS
* 8:	IN10	AN_IN		PC0		// Battery voltage
* 9:	IN17	Vrefint		-
* 10:	IN15	TEMP_MOS	PC5
* 11:	IN13	TEMP_MOTOR	PC3
*/

#define HW_ADC_INJ_CHANNELS		2	// Number of current sensors

// Must correspond to the above comment
#define ADC_IND_TEMP_MOTOR		11
void hw_setup_adc_channels(void) {

// Injected channels
}
	// ADC Pins

palSetPadMode(GPIOC, 5, PAL_MODE_INPUT_ANALOG);

Can you check if there are issues?

CTSchorsch
Offline
Last seen: 2 weeks 13 hours ago
Joined: 2018-07-13 09:55
Posts: 101

Hi Teslafly,

i have some similar problems here with my custom hardware. i think it is a adc problem too.

the realtime data in VESC Tool flickers. voltage jumps from 0 to 36V, duty cycle jumps from -200 to +200 and so on. i think that i have a misconfiguration of my ADC readout.

index 13 and 14 are dummy reads to fill the blocks in the adc configuration

/*
*
* 0  (1):  IN0     SENS1
* 1  (2):  IN1     SENS2
* 2  (3):  IN2     SENS3
* 3  (1):  IN10    CURR1
* 4  (2):  IN11    CURR2
* 5  (3):  IN12    CURR3
* 8  (3):  IN3     TEMP_MOS
* 9  (1):  IN14    TEMP_MOTOR
* 10 (2):  IN15
* 11 (3):  IN13    AN_IN
* 12 (1):  Vrefint
*/


    // ADC1 regular channels

// Injected channels