diff options
author | Amaury Pouly <amaury.pouly@gmail.com> | 2012-03-17 17:39:27 +0100 |
---|---|---|
committer | Amaury Pouly <amaury.pouly@gmail.com> | 2012-03-17 17:42:49 +0100 |
commit | e5b5041583e389e6866b210683a09c97a10077d3 (patch) | |
tree | 256bc4b1f0fbccce21295afbda907988be78f3bb /firmware/target/arm/imx233/adc-imx233.c | |
parent | 7676dae3e0f279d4b193f1c9abf8977c8f52e5d2 (diff) | |
download | rockbox-e5b5041583e389e6866b210683a09c97a10077d3.tar.gz rockbox-e5b5041583e389e6866b210683a09c97a10077d3.zip |
imx233/fuze+: rework lradc/adc code, add external temperature sensing(battery)
Rework code to be more useful:
- move battery channel init to lradc
- always init lradc from system (previously from adc)
- don't reserve channels for vddio, nmos or pmos
- implement external temperature sensing using current source
- use this for battery sensing on the Fuze+ (calibration needed)
Change-Id: I5f9a24b9243db7d1e6bdb16b84bc891e61d0c318
Diffstat (limited to 'firmware/target/arm/imx233/adc-imx233.c')
-rw-r--r-- | firmware/target/arm/imx233/adc-imx233.c | 77 |
1 files changed, 33 insertions, 44 deletions
diff --git a/firmware/target/arm/imx233/adc-imx233.c b/firmware/target/arm/imx233/adc-imx233.c index 08adba442d..b24f7f6c43 100644 --- a/firmware/target/arm/imx233/adc-imx233.c +++ b/firmware/target/arm/imx233/adc-imx233.c | |||
@@ -25,46 +25,11 @@ | |||
25 | #include "system.h" | 25 | #include "system.h" |
26 | #include "adc-imx233.h" | 26 | #include "adc-imx233.h" |
27 | 27 | ||
28 | /* dedicate two channels to temperature sensing | ||
29 | * dedicate channel 7 to battery | ||
30 | * and channel 6 to vddio */ | ||
31 | static int pmos_chan, nmos_chan; | ||
32 | static int battery_chan, vddio_chan; | ||
33 | static int battery_delay_chan; | ||
34 | |||
35 | void adc_init(void) | 28 | void adc_init(void) |
36 | { | 29 | { |
37 | imx233_lradc_init(); | ||
38 | /* reserve channels 6 for vddio and 7 for battery (special for conversion) */ | ||
39 | battery_chan = 7; | ||
40 | vddio_chan = 6; | ||
41 | imx233_lradc_reserve_channel(battery_chan); | ||
42 | imx233_lradc_reserve_channel(vddio_chan); | ||
43 | /* reserve any channels for PMOS and NMOS */ | ||
44 | pmos_chan = imx233_lradc_acquire_channel(TIMEOUT_NOBLOCK); | ||
45 | if(pmos_chan < 0) panicf("No LRADC channel for PMOS !"); | ||
46 | nmos_chan = imx233_lradc_acquire_channel(TIMEOUT_NOBLOCK); | ||
47 | if(nmos_chan < 0) panicf("No LRADC channel for NMOS !"); | ||
48 | |||
49 | /* setup them for the simplest use: no accumulation, no division*/ | ||
50 | imx233_lradc_setup_channel(battery_chan, false, false, 0, HW_LRADC_CHANNEL_BATTERY); | ||
51 | imx233_lradc_setup_channel(vddio_chan, false, false, 0, HW_LRADC_CHANNEL_VDDIO); | ||
52 | imx233_lradc_setup_channel(nmos_chan, false, false, 0, HW_LRADC_CHANNEL_NMOS_THIN); | ||
53 | imx233_lradc_setup_channel(pmos_chan, false, false, 0, HW_LRADC_CHANNEL_PMOS_THIN); | ||
54 | /* setup delay channel for battery for automatic reading and scaling */ | ||
55 | battery_delay_chan = 0; | ||
56 | imx233_lradc_reserve_delay(battery_delay_chan); | ||
57 | /* setup delay to trigger battery channel and retrigger itself. | ||
58 | * The counter runs at 2KHz so a delay of 200 will trigger 10 | ||
59 | * conversions per seconds */ | ||
60 | imx233_lradc_setup_delay(battery_delay_chan, 1 << battery_chan, | ||
61 | 1 << battery_delay_chan, 0, 200); | ||
62 | imx233_lradc_kick_delay(battery_delay_chan); | ||
63 | /* enable automatic conversion, use Li-Ion type battery */ | ||
64 | imx233_lradc_setup_battery_conversion(true, HW_LRADC_CONVERSION__SCALE_FACTOR__LI_ION); | ||
65 | } | 30 | } |
66 | 31 | ||
67 | int adc_read_physical_ex(int virt) | 32 | static short adc_read_physical_ex(int virt) |
68 | { | 33 | { |
69 | imx233_lradc_clear_channel(virt); | 34 | imx233_lradc_clear_channel(virt); |
70 | imx233_lradc_kick_channel(virt); | 35 | imx233_lradc_kick_channel(virt); |
@@ -72,27 +37,51 @@ int adc_read_physical_ex(int virt) | |||
72 | return imx233_lradc_read_channel(virt); | 37 | return imx233_lradc_read_channel(virt); |
73 | } | 38 | } |
74 | 39 | ||
75 | int adc_read_physical(int src) | 40 | static short adc_read_physical(int src, bool div2) |
76 | { | 41 | { |
77 | int virt = imx233_lradc_acquire_channel(TIMEOUT_BLOCK); | 42 | int virt = imx233_lradc_acquire_channel(TIMEOUT_BLOCK); |
78 | // divide by two for wider ranger | 43 | // divide by two for wider ranger |
79 | imx233_lradc_setup_channel(virt, true, false, 0, src); | 44 | imx233_lradc_setup_channel(virt, div2, false, 0, src); |
80 | int val = adc_read_physical_ex(virt); | 45 | int val = adc_read_physical_ex(virt); |
81 | imx233_lradc_release_channel(virt); | 46 | imx233_lradc_release_channel(virt); |
82 | return val; | 47 | return val; |
83 | } | 48 | } |
84 | 49 | ||
85 | unsigned short adc_read_virtual(int c) | 50 | static short adc_read_virtual(int c) |
86 | { | 51 | { |
87 | switch(c) | 52 | switch(c) |
88 | { | 53 | { |
89 | case IMX233_ADC_BATTERY: | 54 | case IMX233_ADC_BATTERY: |
90 | return adc_read_physical_ex(battery_chan); | 55 | return imx233_lradc_read_battery_voltage(); |
91 | case IMX233_ADC_VDDIO: | 56 | case IMX233_ADC_VDDIO: |
92 | return adc_read_physical_ex(vddio_chan); | 57 | /* VddIO pin has a builtin 2:1 divide */ |
58 | return adc_read_physical(HW_LRADC_CHANNEL_VDDIO, false); | ||
59 | case IMX233_ADC_VDD5V: | ||
60 | /* Vdd5V pin has a builtin 4:1 divide */ | ||
61 | return adc_read_physical(HW_LRADC_CHANNEL_5V, false) * 2; | ||
93 | case IMX233_ADC_DIE_TEMP: | 62 | case IMX233_ADC_DIE_TEMP: |
94 | // do kelvin to celsius conversion | 63 | { |
95 | return imx233_lradc_sense_die_temperature(nmos_chan, pmos_chan) - 273; | 64 | // don't block on second channel otherwise we might deadlock ! |
65 | int nmos_chan = imx233_lradc_acquire_channel(TIMEOUT_BLOCK); | ||
66 | int pmos_chan = imx233_lradc_acquire_channel(TIMEOUT_NOBLOCK); | ||
67 | int val = 0; | ||
68 | if(pmos_chan >= 0) | ||
69 | { | ||
70 | val = imx233_lradc_sense_die_temperature(nmos_chan, pmos_chan) - 273; | ||
71 | imx233_lradc_release_channel(pmos_chan); | ||
72 | } | ||
73 | imx233_lradc_release_channel(nmos_chan); | ||
74 | return val; | ||
75 | } | ||
76 | #ifdef IMX233_ADC_BATT_TEMP_SENSOR | ||
77 | case IMX233_ADC_BATT_TEMP: | ||
78 | { | ||
79 | int virt = imx233_lradc_acquire_channel(TIMEOUT_BLOCK); | ||
80 | int val = imx233_lradc_sense_ext_temperature(virt, IMX233_ADC_BATT_TEMP_SENSOR); | ||
81 | imx233_lradc_release_channel(virt); | ||
82 | return val; | ||
83 | } | ||
84 | #endif | ||
96 | default: | 85 | default: |
97 | return 0; | 86 | return 0; |
98 | } | 87 | } |
@@ -104,5 +93,5 @@ unsigned short adc_read(int channel) | |||
104 | if(c < 0) | 93 | if(c < 0) |
105 | return adc_read_virtual(c); | 94 | return adc_read_virtual(c); |
106 | else | 95 | else |
107 | return adc_read_physical(c); | 96 | return adc_read_physical(c, true); |
108 | } | 97 | } |