Browse Source

bsp:cvitek: add calibration for adc

The ADC controller needs to be calibrated during the initialization
phase, otherwise the measured voltage value will be inaccurate.

Signed-off-by: Chen Wang <unicorn_wang@outlook.com>
Chen Wang 1 year ago
parent
commit
d8d0af9143
2 changed files with 25 additions and 1 deletions
  1. 7 1
      bsp/cvitek/drivers/drv_adc.c
  2. 18 0
      bsp/cvitek/drivers/drv_adc.h

+ 7 - 1
bsp/cvitek/drivers/drv_adc.c

@@ -103,7 +103,13 @@ static const struct rt_adc_ops _adc_ops =
 int rt_hw_adc_init(void)
 int rt_hw_adc_init(void)
 {
 {
     rt_uint8_t i;
     rt_uint8_t i;
-    for (i = 0; i < sizeof(adc_dev_config) / sizeof(adc_dev_config[0]); i ++)
+
+    for (i = 0; i < sizeof(adc_dev_config) / sizeof(adc_dev_config[0]); i++)
+    {
+        cvi_do_calibration(adc_dev_config[i].base);
+    }
+
+    for (i = 0; i < sizeof(adc_dev_config) / sizeof(adc_dev_config[0]); i++)
     {
     {
         if (rt_hw_adc_register(&adc_dev_config[i].device, adc_dev_config[i].name, &_adc_ops, &adc_dev_config[i]) != RT_EOK)
         if (rt_hw_adc_register(&adc_dev_config[i].device, adc_dev_config[i].name, &_adc_ops, &adc_dev_config[i]) != RT_EOK)
         {
         {

+ 18 - 0
bsp/cvitek/drivers/drv_adc.h

@@ -48,6 +48,11 @@
 #define SARADC_RESULT_MASK                  0x0FFF
 #define SARADC_RESULT_MASK                  0x0FFF
 #define SARADC_RESULT_VALID                 (1 << 15)
 #define SARADC_RESULT_VALID                 (1 << 15)
 
 
+#define SARADC_TEST_OFFSET                  0x030
+#define SARADC_TEST_VREFSEL_BIT             2
+
+#define SARADC_TRIM_OFFSET                  0x034
+
 rt_inline void cvi_set_saradc_ctrl(unsigned long reg_base, rt_uint32_t value)
 rt_inline void cvi_set_saradc_ctrl(unsigned long reg_base, rt_uint32_t value)
 {
 {
     value |= mmio_read_32(reg_base + SARADC_CTRL_OFFSET);
     value |= mmio_read_32(reg_base + SARADC_CTRL_OFFSET);
@@ -78,6 +83,19 @@ rt_inline void cvi_set_cyc(unsigned long reg_base)
     mmio_write_32(reg_base + SARADC_CYC_SET_OFFSET, value);
     mmio_write_32(reg_base + SARADC_CYC_SET_OFFSET, value);
 }
 }
 
 
+rt_inline void cvi_do_calibration(unsigned long reg_base)
+{
+    rt_uint32_t val;
+
+    val = mmio_read_32(reg_base + SARADC_TEST_OFFSET);
+    val |= 1 << SARADC_TEST_VREFSEL_BIT;
+    mmio_write_32(reg_base + SARADC_TEST_OFFSET, val);
+
+    val = mmio_read_32(reg_base + SARADC_TRIM_OFFSET);
+    val |= 0x4;
+    mmio_write_32(reg_base + SARADC_TRIM_OFFSET, val);
+}
+
 int rt_hw_adc_init(void);
 int rt_hw_adc_init(void);
 
 
 #endif /* __DRV_ADC_H__ */
 #endif /* __DRV_ADC_H__ */