Hello,
I believe I found a bug with the routine analogin_read_u16 in the libraries/mbed/targets/HAL/TARGET_KLXX/analogin_api.c file.
On various Freescale MCUs, the ADC unit may have several channels which are multiplexed/sub-divided into channels "a" & "b" (e.x.. ADC4a, ADC5b, etc.) Selection of which sub-channel is controlled through ADCx_CFG2[MUXSEL] .
The analog_init routine sets ADCx_CFG2 appropriately for the pin being setup. The problem happens when the last ADC pin initialized is on a sub-channel that does not match a later pin read which has a different sub channel.
Using the KL16 processor as an example, say you want to use PTE17 & PTE29 as analog inputs. PTE17 is on channel ADC_SE5a while PTE29 is on ADC_SE4b. analog_init is called for PTE17 and then later PTE29 is initialized as well, ADCx_CFG2 will be left configured for the "b" channel.
Now, when analog_read_u16 is called to read PTE17 - it will incorrectly read SE5b instead of SE5a because ADCx_CFG2 is not set to the right mux selection (ADCx_CFG2[MUXSEL]).
analog_read_u16 needs to set the correct sub-channel before doing anything.
My suggestion is add an additional field to the analog_s structure to track the appropriate MUXSEL value for the pin. Then in analogin_read_uint16 set ADCx_CFG2[MUXSEL] to said value before initiating the read.
Maybe something like this:
objects.h
struct analogin_s {
ADCName adc;
uint32_t muxsel;
};
analogin_api.s
analogin_init:
obj->muxsel = ADC_CFG2_MUXSEL_MASK
if (obj->adc & (1 << CHANNELS_A_SHIFT)) {
obj->muxsel = 0;
}
analogin_read_u16:
ADC0->CFG2 = obj->muxsel // ADxxb or ADxxa channels
| ADC_CFG2_ADHSC_MASK // High-Speed Configuration
| ADC_CFG2_ADLSTS(0); // Long Sample Time Select
// start conversion
ADC0->SC1[0] = ADC_SC1_ADCH(obj->adc & ~(1 << CHANNELS_A_SHIFT));
Mike
Hello,
I believe I found a bug with the routine analogin_read_u16 in the libraries/mbed/targets/HAL/TARGET_KLXX/analogin_api.c file.
On various Freescale MCUs, the ADC unit may have several channels which are multiplexed/sub-divided into channels "a" & "b" (e.x.. ADC4a, ADC5b, etc.) Selection of which sub-channel is controlled through ADCx_CFG2[MUXSEL] .
The analog_init routine sets ADCx_CFG2 appropriately for the pin being setup. The problem happens when the last ADC pin initialized is on a sub-channel that does not match a later pin read which has a different sub channel.
Using the KL16 processor as an example, say you want to use PTE17 & PTE29 as analog inputs. PTE17 is on channel ADC_SE5a while PTE29 is on ADC_SE4b. analog_init is called for PTE17 and then later PTE29 is initialized as well, ADCx_CFG2 will be left configured for the "b" channel.
Now, when analog_read_u16 is called to read PTE17 - it will incorrectly read SE5b instead of SE5a because ADCx_CFG2 is not set to the right mux selection (ADCx_CFG2[MUXSEL]).
analog_read_u16 needs to set the correct sub-channel before doing anything.
My suggestion is add an additional field to the analog_s structure to track the appropriate MUXSEL value for the pin. Then in analogin_read_uint16 set ADCx_CFG2[MUXSEL] to said value before initiating the read.
Maybe something like this:
objects.h
analogin_api.s
Mike