Demistify the Complexity of AnalogInput assignements in NETMF, when porting to a Device

Oct 24, 2012 at 4:49 PM
Edited Oct 25, 2012 at 1:38 PM

It took me several days to achieve some tests on the STM32F4 Discovery module regarding the Analog Inputs and their mappings ! Of course not only in testing, but reading and browsing quite all the NETMF porting and SDK folders, to finally catch something that could be part of the answer to my question :

Where is the explanation of this fu... problem that causes my board not to evaluate the Analog entry I'm playing with ?


Well, if someone here had the same comprehension problem : and I'm sure there's regarding to several posts I saw on the forum, I will try to explain in few words how the relationship between physical PINS assignements and Cpu.Channel is built !

First of all, I had a look the the NETMF_for_STM32 on Codeplex, and especially to the DeviceCode/Targets/Native/STM32F4/DeviceCode/STM32F4_Analog, particularly a file called STM32F4_AD_Functions.cpp. In this file, we can see the following :

#define ADCx ADC1
#define RCC_APB2ENR_ADCxEN RCC_APB2ENR_ADC1EN
#define STM32F4_ADC_PINS {0,1,2,3,4,5,6,7,16,17,32,33,34,35,36,37} // ADC1 pins


You can believe me, the ADC_PINS are the one described in the STM32 schematic : PA1 to PA7, PB0 and PB1, PC0 to PC5 (the 0 seems to be for GPIO_NONE...),
At this stage, we can consider that this is an Array of PINS, containing a '0' PIN + 15 other pins that relate to the GPIO that are ADC enabled, so a 16 length array !
In fact this "#define" represent all that we can assign on ADC purpose for this Device, regarding to the ADC1 converter members (STM32 has 2 ported converters ADC1 and ADC3).

Second step, I decided to see about my specific board, which is located in : /Solutions/Discovery4, and particularly the file named platform_selector.h. In his file, we can see a subsequent definition that looks like :


#define STM32F4_ADC 1
#define STM32F4_AD_CHANNELS {1,2,3,8,9,14,15}


As I said, it is subsequent, meaning that not all the existing Analog Inputs have been specified in the Discovery package : only 7 of them

....slience.....
Any question ?
....slience.....

Yes ! Why are those to array containing some values that do not match each other ? For example : no 8,9,14,15 in the first one ! Good question ! The answer is that in the first array, we assign PINS, and in the second one, we assign Array indexes ! And what array is it for ? Of course the STM32F4_ADC_PINS Array ! And effectively, if you take the several values that are in this first array, at the given indexes, you obtain :

INDEX 1....................PIN 1..............PA1
INDEX 2....................PIN 2..............PA2
INDEX 3....................PIN 3..............PA3
INDEX 8....................PIN 16............PB0
INDEX 9....................PIN 17............PB1
INDEX 14..................PIN 36............PC4
INDEX 15..................PIN 37............PC5

Do you think it is finished there ? Of course not, let us go to the STEP 3, and have a look at the Cpu.AnalogChannel enumeration that define the serve the ha AnalogInput class constructor to assign the right PIN to your device.

  • First I tried to override the HardwareProvider function called GetAnalogPinForChannel to make each channel match to the relaed pin :

 

public override Cpu.Pin GetAnalogPinForChannel(Cpu.AnalogChannel channel)
        {
            switch (channel)
            {
                case Cpu.AnalogChannel.ANALOG_0:
                    return Pins.GPIO_PIN_A_1;
                case Cpu.AnalogChannel.ANALOG_1:
                    return Pins.GPIO_PIN_A_2;
                case Cpu.AnalogChannel.ANALOG_2:
                    return Pins.GPIO_PIN_A_3;
                case Cpu.AnalogChannel.ANALOG_3:
                    return Pins.GPIO_PIN_B_0;
                case Cpu.AnalogChannel.ANALOG_4:
                    return Pins.GPIO_PIN_B_1;
                case Cpu.AnalogChannel.ANALOG_5:
                    return Pins.GPIO_PIN_C_4;
                case Cpu.AnalogChannel.ANALOG_6:
                    return Pins.GPIO_PIN_C_5;
                default:
                    return Pins.GPIO_NONE;
            }
        }


But finally i realized that is would change nothing if I did not override, as the mapping is done directly at the C++ level classes between the several files we saw just above. The only thing that can justify to do such overriding would be to manage a subsequence of the whole STM32 ADC PINS at the managedCode level for example.

SO this makes sense to several postulate :

  • Choosing if you need more AD Inputs than it is provided by a specific board is not so easy as to implement overriding on the managed code level ! It has to refer in any cases in which the board provider decided or not to mask part of them using a subsequent array of authorized PINS in its implementation !

 

  • We have to be very careful when looking at the NETMF source code, in that array and indexes manipulations are sometimes causing misunderstandings (it was the case for me at least)

 

  • If you want to be sure on what you can do with a board, have a look at those 3 important files that we saw here. They will help you to understand how the link is made between physical, logical and managed level of implementations !


I hope this will be instructive for some of you !
It took me several days to achieve some tests on the STM32F4 Discovery module regarding the Analog Inputs and their mappings ! Of course not only in testing, but reading and browsing quite all the NETMF porting and SDK folders, to finally catch something that could be part of the answer to my question :

Where is the explanation of this fu... problem that causes my board not to evaluate the Analog entry I'm playing with ?


Well, if someone here had the same comprehension problem : and I'm sure there's regarding to several posts I saw on the forum, I will try to explain in few words how the relationship between physical PINS assignements and Cpu.Channel is built !

First of all, I had a look the the NETMF_for_STM32 on Codeplex, and especially to the DeviceCode/Targets/Native/STM32F4/DeviceCode/STM32F4_Analog, particularly a file called STM32F4_AD_Functions.cpp. In this file, we can see the following :

#define ADCx ADC1
#define RCC_APB2ENR_ADCxEN RCC_APB2ENR_ADC1EN
#define STM32F4_ADC_PINS {0,1,2,3,4,5,6,7,16,17,32,33,34,35,36,37} // ADC1 pins


You can believe me, the ADC_PINS are the one described in the STM32 schematic : PA1 to PA7, PB0 and PB1, PC0 to PC5 (the 0 seems to be for GPIO_NONE...),
At this stage, we can consider that this is an Array of PINS, containing a '0' PIN + 15 other pins that relate to the GPIO that are ADC enabled, so a 16 length array !
In fact this "#define" represent all that we can assign on ADC purpose for this Device, regarding to the ADC1 converter members (STM32 has 2 ported converters ADC1 and ADC3).

Second step, I decided to see about my specific board, which is located in : /Solutions/Discovery4, and particularly the file named platform_selector.h. In his file, we can see a subsequent definition that looks like :


#define STM32F4_ADC 1
#define STM32F4_AD_CHANNELS {1,2,3,8,9,14,15}


As I said, it is subsequent, meaning that not all the existing Analog Inputs have been specified in the Discovery package : only 7 of them

....slience.....
Any question ?
....slience.....

Yes ! Why are those to array containing some values that do not match each other ? For example : no 8,9,14,15 in the first one ! Good question ! The answer is that in the first array, we assign PINS, and in the second one, we assign Array indexes ! And what array is it for ? Of course the STM32F4_ADC_PINS Array ! And effectively, if you take the several values that are in this first array, at the given indexes, you obtain :

INDEX 1....................PIN 1..............PA1
INDEX 2....................PIN 2..............PA2
INDEX 3....................PIN 3..............PA3
INDEX 8....................PIN 16............PB0
INDEX 9....................PIN 17............PB1
INDEX 14..................PIN 36............PC4
INDEX 15..................PIN 37............PC5

Do you think it is finished there ? Of course not, let us go to the STEP 3, and have a look at the Cpu.AnalogChannel enumeration that define the serve the ha AnalogInput class constructor to assign the right PIN to your device.

  • First I tried to override the HardwareProvider function called GetAnalogPinForChannel to make each channel match to the relaed pin :

 

public override Cpu.Pin GetAnalogPinForChannel(Cpu.AnalogChannel channel)
        {
            switch (channel)
            {
                case Cpu.AnalogChannel.ANALOG_0:
                    return Pins.GPIO_PIN_A_1;
                case Cpu.AnalogChannel.ANALOG_1:
                    return Pins.GPIO_PIN_A_2;
                case Cpu.AnalogChannel.ANALOG_2:
                    return Pins.GPIO_PIN_A_3;
                case Cpu.AnalogChannel.ANALOG_3:
                    return Pins.GPIO_PIN_B_0;
                case Cpu.AnalogChannel.ANALOG_4:
                    return Pins.GPIO_PIN_B_1;
                case Cpu.AnalogChannel.ANALOG_5:
                    return Pins.GPIO_PIN_C_4;
                case Cpu.AnalogChannel.ANALOG_6:
                    return Pins.GPIO_PIN_C_5;
                default:
                    return Pins.GPIO_NONE;
            }
        }


But finally i realized that is would change nothing if I did not override, as the mapping is done directly at the C++ level classes between the several files we saw just above. The only thing that can justify to do such overriding would be to manage a subsequence of the whole STM32 ADC PINS at the managedCode level for example.

SO this makes sense to several postulate :

  • Choosing if you need more AD Inputs than it is provided by a specific board is not so easy as to implement overriding on the managed code level ! It has to refer in any cases in which the board provider decided or not to mask part of them using a subsequent array of authorized PINS in its implementation !

 

  • We have to be very careful when looking at the NETMF source code, in that array and indexes manipulations are sometimes causing misunderstandings (it was the case for me at least)

 

  • If you want to be sure on what you can do with a board, have a look at those 3 important files that we saw here. They will help you to understand how the link is made between physical, logical and managed level of implementations !


I hope this will be instructive for some of you !