summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--firmware/target/arm/imx233/adc-imx233.c19
-rw-r--r--firmware/target/arm/imx233/adc-imx233.h2
-rw-r--r--firmware/target/arm/imx233/lradc-imx233.c57
-rw-r--r--firmware/target/arm/imx233/lradc-imx233.h11
-rw-r--r--firmware/target/arm/imx233/touchscreen-imx233.c2
5 files changed, 83 insertions, 8 deletions
diff --git a/firmware/target/arm/imx233/adc-imx233.c b/firmware/target/arm/imx233/adc-imx233.c
index 9b5af82d5d..a6025cfde9 100644
--- a/firmware/target/arm/imx233/adc-imx233.c
+++ b/firmware/target/arm/imx233/adc-imx233.c
@@ -20,6 +20,7 @@
****************************************************************************/
#include "adc-imx233.h"
+#include "power-imx233.h"
void adc_init(void)
{
@@ -35,7 +36,7 @@ static short adc_read_physical_ex(int virt)
static short adc_read_physical(int src, bool div2)
{
- int virt = imx233_lradc_acquire_channel(TIMEOUT_BLOCK);
+ int virt = imx233_lradc_acquire_channel(src, TIMEOUT_BLOCK);
// divide by two for wider ranger
imx233_lradc_setup_channel(virt, div2, false, 0, src);
int val = adc_read_physical_ex(virt);
@@ -52,14 +53,17 @@ static short adc_read_virtual(int c)
case IMX233_ADC_VDDIO:
/* VddIO pin has a builtin 2:1 divide */
return adc_read_physical(LRADC_SRC_VDDIO, false);
+#if IMX233_SUBTARGET >= 3700
case IMX233_ADC_VDD5V:
/* Vdd5V pin has a builtin 4:1 divide */
return adc_read_physical(LRADC_SRC_5V, false) * 2;
+#endif
case IMX233_ADC_DIE_TEMP:
{
+#if IMX233_SUBTARGET >= 3700
// don't block on second channel otherwise we might deadlock !
- int nmos_chan = imx233_lradc_acquire_channel(TIMEOUT_BLOCK);
- int pmos_chan = imx233_lradc_acquire_channel(TIMEOUT_NOBLOCK);
+ int nmos_chan = imx233_lradc_acquire_channel(LRADC_SRC_NMOS_THIN, TIMEOUT_BLOCK);
+ int pmos_chan = imx233_lradc_acquire_channel(LRADC_SRC_PMOS_THIN, TIMEOUT_NOBLOCK);
int val = 0;
if(pmos_chan >= 0)
{
@@ -67,12 +71,19 @@ static short adc_read_virtual(int c)
imx233_lradc_release_channel(pmos_chan);
}
imx233_lradc_release_channel(nmos_chan);
+#else
+ int min, max, val;
+ if(imx233_power_sense_die_temperature(&min, &max) < 0)
+ val = -1;
+ else
+ val = (max + min) / 2;
+#endif
return val;
}
#ifdef IMX233_BATT_TEMP_SENSOR
case IMX233_ADC_BATT_TEMP:
{
- int virt = imx233_lradc_acquire_channel(TIMEOUT_BLOCK);
+ int virt = imx233_lradc_acquire_channel(IMX233_BATT_TEMP_SENSOR, TIMEOUT_BLOCK);
int val = imx233_lradc_sense_ext_temperature(virt, IMX233_BATT_TEMP_SENSOR);
imx233_lradc_release_channel(virt);
return val;
diff --git a/firmware/target/arm/imx233/adc-imx233.h b/firmware/target/arm/imx233/adc-imx233.h
index 09fd7eb013..f833e17be0 100644
--- a/firmware/target/arm/imx233/adc-imx233.h
+++ b/firmware/target/arm/imx233/adc-imx233.h
@@ -31,7 +31,9 @@
#define IMX233_ADC_BATTERY -1 /* Battery voltage (mV) */
#define IMX233_ADC_DIE_TEMP -2 /* Die temperature (°C) */
#define IMX233_ADC_VDDIO -3 /* VddIO voltage (mV) */
+#if IMX233_SUBTARGET >= 3700
#define IMX233_ADC_VDD5V -4 /* Vdd5V voltage (mV) */
+#endif
#ifdef IMX233_BATT_TEMP_SENSOR
#define IMX233_ADC_BATT_TEMP -5 /* Battery temperature (°C) */
#endif
diff --git a/firmware/target/arm/imx233/lradc-imx233.c b/firmware/target/arm/imx233/lradc-imx233.c
index 4fe05f36f7..d95a002663 100644
--- a/firmware/target/arm/imx233/lradc-imx233.c
+++ b/firmware/target/arm/imx233/lradc-imx233.c
@@ -25,7 +25,11 @@
#include "stdlib.h"
/* channels */
+#if IMX233_SUBTARGET >= 3700
static struct channel_arbiter_t channel_arbiter;
+#else
+static struct semaphore channel_sema[LRADC_NUM_CHANNELS];
+#endif
/* delay channels */
static struct channel_arbiter_t delay_arbiter;
/* battery is very special, dedicate a channel and a delay to it */
@@ -44,6 +48,7 @@ void INT_LRADC_CH(int chan)
{
if(irq_cb[chan])
irq_cb[chan](chan);
+ imx233_lradc_clear_channel_irq(chan);
}
define_cb(0)
@@ -58,6 +63,7 @@ define_cb(7)
void imx233_lradc_set_channel_irq_callback(int channel, lradc_irq_fn_t cb)
{
irq_cb[channel] = cb;
+ imx233_icoll_enable_interrupt(INT_SRC_LRADC_CHx(channel), cb != NULL);
}
void imx233_lradc_setup_channel(int channel, bool div2, bool acc, int nr_samples, int src)
@@ -68,8 +74,23 @@ void imx233_lradc_setup_channel(int channel, bool div2, bool acc, int nr_samples
BF_SETV(LRADC_CTRL2, DIVIDE_BY_TWO, 1 << channel);
else
BF_CLRV(LRADC_CTRL2, DIVIDE_BY_TWO, 1 << channel);
+#if IMX233_SUBTARGET >= 3700
HW_LRADC_CTRL4_CLR = BM_LRADC_CTRL4_LRADCxSELECT(channel);
HW_LRADC_CTRL4_SET = src << BP_LRADC_CTRL4_LRADCxSELECT(channel);
+#else
+ if(channel == 6)
+ {
+ BF_CLR(LRADC_CTRL2, LRADC6SELECT);
+ BF_SETV(LRADC_CTRL2, LRADC6SELECT, src);
+ }
+ else if(channel == 7)
+ {
+ BF_CLR(LRADC_CTRL2, LRADC7SELECT);
+ BF_SETV(LRADC_CTRL2, LRADC7SELECT, src);
+ }
+ else if(channel != src)
+ panicf("cannot configure channel %d for source %d", channel, src);
+#endif
}
void imx233_lradc_setup_delay(int dchan, int trigger_lradc, int trigger_delays,
@@ -126,8 +147,10 @@ void imx233_lradc_clear_channel(int channel)
BF_CLRn(LRADC_CHn, channel, VALUE);
}
-int imx233_lradc_acquire_channel(int timeout)
+#if IMX233_SUBTARGET >= 3700
+int imx233_lradc_acquire_channel(int src, int timeout)
{
+ (void) src;
return arbiter_acquire(&channel_arbiter, timeout);
}
@@ -140,6 +163,26 @@ void imx233_lradc_reserve_channel(int channel)
{
return arbiter_reserve(&channel_arbiter, channel);
}
+#else
+int imx233_lradc_acquire_channel(int src, int timeout)
+{
+ int channel = src <= LRADC_SRC_BATTERY ? src : 6;
+ if(semaphore_wait(&channel_sema[channel], timeout) == OBJ_WAIT_TIMEDOUT)
+ return -1;
+ return channel;
+}
+
+void imx233_lradc_release_channel(int chan)
+{
+ semaphore_release(&channel_sema[chan]);
+}
+
+void imx233_lradc_reserve_channel(int channel)
+{
+ if(imx233_lradc_acquire_channel(channel, 0) == -1)
+ panicf("Cannot reserve a used channel");
+}
+#endif
int imx233_lradc_acquire_delay(int timeout)
{
@@ -156,6 +199,7 @@ void imx233_lradc_reserve_delay(int channel)
return arbiter_reserve(&delay_arbiter, channel);
}
+#if IMX233_SUBTARGET >= 3700
int imx233_lradc_sense_die_temperature(int nmos_chan, int pmos_chan)
{
imx233_lradc_setup_channel(nmos_chan, false, false, 0, LRADC_SRC_NMOS_THIN);
@@ -177,6 +221,7 @@ int imx233_lradc_sense_die_temperature(int nmos_chan, int pmos_chan)
// return diff * 1.012 / 4
return (diff * 1012) / 4000;
}
+#endif
/* set to 0 to disable current source */
static void imx233_lradc_set_temp_isrc(int sensor, int value)
@@ -278,7 +323,15 @@ bool imx233_lradc_read_touch_detect(void)
void imx233_lradc_init(void)
{
+ /* On STMP3700+, any channel can measure any source but on STMP3600 only
+ * channels 6 and 7 can measure all sources. Channel 7 being dedicated to
+ * battery, only channel 6 is available for free use */
+#if IMX233_SUBTARGET >= 3700
arbiter_init(&channel_arbiter, LRADC_NUM_CHANNELS);
+#else
+ for(int i = 0; i < LRADC_NUM_CHANNELS; i++)
+ semaphore_init(&channel_sema[i], 1, 1);
+#endif
arbiter_init(&delay_arbiter, LRADC_NUM_DELAYS);
// enable block
imx233_reset_block(&HW_LRADC_CTRL0);
@@ -287,7 +340,9 @@ void imx233_lradc_init(void)
// disable temperature sensors
BF_CLR(LRADC_CTRL2, TEMP_SENSOR_IENABLE0);
BF_CLR(LRADC_CTRL2, TEMP_SENSOR_IENABLE1);
+#if IMX233_SUBTARGET >= 3700
BF_SET(LRADC_CTRL2, TEMPSENSE_PWD);
+#endif
// set frequency
BF_CLR(LRADC_CTRL3, CYCLE_TIME);
BF_SETV(LRADC_CTRL3, CYCLE_TIME_V, 6MHZ);
diff --git a/firmware/target/arm/imx233/lradc-imx233.h b/firmware/target/arm/imx233/lradc-imx233.h
index d1529f4266..f274db3520 100644
--- a/firmware/target/arm/imx233/lradc-imx233.h
+++ b/firmware/target/arm/imx233/lradc-imx233.h
@@ -55,10 +55,12 @@
#define LRADC_SRC_NMOS_THICK LRADC_SRC(10)
#define LRADC_SRC_PMOS_THICK LRADC_SRC(11)
#define LRADC_SRC_PMOS_THICK LRADC_SRC(11)
+#if IMX233_SUBTARGET >= 3700
#define LRADC_SRC_USB_DP LRADC_SRC(12)
#define LRADC_SRC_USB_DN LRADC_SRC(13)
#define LRADC_SRC_VBG LRADC_SRC(14)
#define LRADC_SRC_5V LRADC_SRC(15)
+#endif
/* frequency of the delay counter */
#define LRADC_DELAY_FREQ 2000
@@ -72,14 +74,17 @@ void imx233_lradc_setup_delay(int dchan, int trigger_lradc, int trigger_delays,
void imx233_lradc_clear_channel_irq(int channel);
bool imx233_lradc_read_channel_irq(int channel);
void imx233_lradc_enable_channel_irq(int channel, bool enable);
+/* a non-null cb will enable the icoll interrupt, a null one will disable it
+ * NOTE the channel irq is automatically cleared */
void imx233_lradc_set_channel_irq_callback(int channel, lradc_irq_fn_t cb);
void imx233_lradc_kick_channel(int channel);
void imx233_lradc_kick_delay(int dchan);
void imx233_lradc_wait_channel(int channel);
int imx233_lradc_read_channel(int channel);
void imx233_lradc_clear_channel(int channel);
-// acquire a virtual channel, returns -1 on timeout, channel otherwise */
-int imx233_lradc_acquire_channel(int timeout);
+/* acquire a channel, returns -1 on timeout, channel otherwise
+ * the returned channel is garanteed to be able measure source src */
+int imx233_lradc_acquire_channel(int src, int timeout);
void imx233_lradc_release_channel(int chan);
// doesn't check that channel is in use!
void imx233_lradc_reserve_channel(int channel);
@@ -96,9 +101,11 @@ void imx233_lradc_enable_touch_detect_irq(bool enable);
void imx233_lradc_clear_touch_detect_irq(void);
bool imx233_lradc_read_touch_detect(void);
+#if IMX233_SUBTARGET >= 3700
/* enable sensing and return temperature in kelvin,
* channels needs not to be configured */
int imx233_lradc_sense_die_temperature(int nmos_chan, int pmos_chan);
+#endif
/* return *raw* external temperature, might need some transformation
* channel needs not to be configured */
int imx233_lradc_sense_ext_temperature(int chan, int sensor);
diff --git a/firmware/target/arm/imx233/touchscreen-imx233.c b/firmware/target/arm/imx233/touchscreen-imx233.c
index 4f35110df7..e76d7a49e3 100644
--- a/firmware/target/arm/imx233/touchscreen-imx233.c
+++ b/firmware/target/arm/imx233/touchscreen-imx233.c
@@ -167,7 +167,7 @@ static void touch_channel_irq(int chan)
void imx233_touchscreen_init(void)
{
- touch_chan = imx233_lradc_acquire_channel(TIMEOUT_NOBLOCK);
+ touch_chan = imx233_lradc_acquire_channel(LRADC_SRC_XPLUS, TIMEOUT_NOBLOCK);
touch_delay = imx233_lradc_acquire_delay(TIMEOUT_NOBLOCK);
if(touch_chan < 0 || touch_delay < 0)
panicf("Cannot acquire channel and delays for touchscreen measurement");