单片机/MCU论坛
直播中

辛书伟

12年用户 110经验值
擅长:嵌入式技术
私信 关注
[文章]

【RA4M2设计挑战赛】模拟IIC isl29035驱动

参照上次文档添加模拟iic
https://bbs.elecfans.com/jishu_2336359_1_1.html
编写光照模块 isl29035 模块驱动
  1. #define DBG_TAG "sensor.isl29035"
  2. #define DBG_LVL DBG_INFO
  3. #include

  4. #include
  5. #include

  6. #include
  7. #include "hal_data.h"
  8. #include "isl29035.h"

  9. /*
  10. * Global Variables
  11. */

  12. uint8_t set_regs_data[2];
  13. struct isl29035_dev isl_dev;

  14. static char *i2c_bus_name = NULL;
  15. static struct rt_i2c_bus_device *i2c_bus = NULL;


  16. /** Performs a write operation on an I2C Master device.
  17. * @param[in] p_src     Pointer to the location to get write data from.
  18. * @param[in] bytes     Number of bytes to write.
  19. */
  20. fsp_err_t hal_i2c_write(uint8_t *const p_src,
  21.                         uint32_t const   bytes)
  22. {
  23.     struct rt_i2c_msg msgs[1];

  24.     msgs[0].addr = (rt_uint16_t)ISL29035_I2C_ADDR;
  25.     msgs[0].buf = p_src;
  26.     msgs[0].len = bytes;
  27.     msgs[0].flags = RT_I2C_WR ;

  28.     if (rt_i2c_transfer(i2c_bus, msgs, 1) == 1)
  29.     {
  30.         return FSP_SUCCESS;
  31.     }
  32.     else
  33.     {
  34.         LOG_E("i2c_write ERROR_I2C");
  35.         return -1;
  36.     }
  37. }

  38. /** Performs a read operation on an I2C Master device.
  39. * @param[in] p_dest    Pointer to the location to store read data.
  40. * @param[in] bytes     Number of bytes to read.
  41. */
  42. fsp_err_t hal_i2c_read(uint8_t *const p_dest,
  43.                        uint32_t const  bytes)
  44. {
  45.     struct rt_i2c_msg msgs[1];
  46.     msgs[0].addr = (rt_uint16_t)ISL29035_I2C_ADDR;
  47.     msgs[0].buf = p_dest;
  48.     msgs[0].len = bytes;
  49.     msgs[0].flags = RT_I2C_RD;

  50.     if (rt_i2c_transfer(i2c_bus, msgs, 1) == 1)
  51.     {
  52.         return FSP_SUCCESS;
  53.     }
  54.     else
  55.     {
  56.         LOG_E("i2c_read ERROR_I2C");
  57.         return -1;
  58.     }
  59. }

  60. fsp_err_t hal_i2c_open(char *bus_name)
  61. {
  62.     i2c_bus_name = bus_name;

  63.     i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(i2c_bus_name);
  64.     if (i2c_bus == RT_NULL)
  65.     {
  66.         LOG_E("Device not found!");
  67.         return FSP_ERR_ASSERTION;
  68.     }
  69.     return FSP_SUCCESS;
  70. }

  71. fsp_err_t hal_i2c_close(void)
  72. {

  73.     return FSP_SUCCESS;
  74. }


  75. //ISL29035
  76. fsp_err_t isl29035_get_regs(uint8_t reg_addr,
  77.                             uint8_t *data,
  78.                             uint16_t len,
  79.                             const struct isl29035_dev *dev)
  80. {
  81.     fsp_err_t err         = FSP_SUCCESS;

  82.     /* Get register address to sensor */
  83.     err = hal_i2c_write(®_addr, 1);
  84.     /* handle error */
  85.     if (FSP_SUCCESS != err)
  86.     {
  87.         LOG_E("** hal_i2c_write API failed **
  88. ");
  89.     }
  90.     else
  91.     {
  92.         /* Read only when I2C write and its callback event is successful */
  93.         err = hal_i2c_read(data, len);
  94.         /* handle error */
  95.         if (FSP_SUCCESS != err)
  96.         {
  97.             LOG_E("** hal_i2c_read API failed **
  98. ");
  99.             //  Do nothing, the error is returned in the end
  100.         }
  101.     }
  102.     return err;
  103. }

  104. /*!
  105. * [url=home.php?mod=space&uid=2666770]@Brief[/url] This API writes the given data to the register address
  106. * of sensor.
  107. */
  108. fsp_err_t isl29035_set_regs(uint8_t reg_addr,
  109.                             uint8_t *data,
  110.                             uint16_t len,
  111.                             const struct isl29035_dev *dev)
  112. {
  113.     fsp_err_t err         = FSP_SUCCESS;

  114.     set_regs_data[0] = reg_addr;
  115.     set_regs_data[1] = *data;

  116.     err = hal_i2c_write(set_regs_data, len);
  117.     return err;
  118. }

  119. fsp_err_t isl29035_set_mode(struct isl29035_dev *dev)
  120. {
  121.     fsp_err_t err         = FSP_SUCCESS;
  122.     uint8_t val;

  123.     err = isl29035_get_regs(ISL29035_COMMAND_I_REG, &val, 1, dev);
  124.     if (FSP_SUCCESS == err)
  125.     {
  126.         val = (uint8_t)((val & ISL29035_OPMODE_MASK) | dev->adc_mode);

  127.         err = isl29035_set_regs(ISL29035_COMMAND_I_REG, &val, 2, dev);
  128.     }
  129.     return err;
  130. }

  131. fsp_err_t isl29035_set_range(struct isl29035_dev *dev)
  132. {
  133.     fsp_err_t err         = FSP_SUCCESS;
  134.     uint8_t val;

  135.     err = isl29035_get_regs(ISL29035_COMMAND_II_REG, &val, 1, dev);
  136.     if (FSP_SUCCESS == err)
  137.     {
  138.         val = (uint8_t)((val & ISL29035_LUX_RANGE_MASK) | dev->adc_range);

  139.         err = isl29035_set_regs(ISL29035_COMMAND_II_REG, &val, 2, dev);
  140.     }
  141.     return err;
  142. }

  143. fsp_err_t isl29035_set_res(struct isl29035_dev *dev)
  144. {
  145.     fsp_err_t err         = FSP_SUCCESS;
  146.     uint8_t val;

  147.     err = isl29035_get_regs(ISL29035_COMMAND_II_REG, &val, 1, dev);
  148.     if (FSP_SUCCESS == err)
  149.     {
  150.         val = (uint8_t)((val & ISL29035_ADC_RES_MASK) | dev->adc_res);

  151.         err = isl29035_set_regs(ISL29035_COMMAND_II_REG, &val, 2, dev);
  152.     }
  153.     return err;
  154. }

  155. fsp_err_t isl29035_init(struct isl29035_dev *dev, char *bus_name)
  156. {
  157.     uint8_t device_isl29035_id = 0x00;
  158.     fsp_err_t err     = FSP_SUCCESS;
  159.     uint8_t val;

  160.     /* opening IIC master module */
  161.     err = hal_i2c_open(bus_name);
  162.     /* handle error */
  163.     if (FSP_SUCCESS != err)
  164.     {
  165.         LOG_E("** hal_i2c_open API failed **
  166. ");
  167.         return err;
  168.     }

  169.     /* Get device ID as a start of communication */
  170.     err = isl29035_get_regs(ISL29035_REG_DEVICE_ID, &device_isl29035_id, 1, dev);

  171.     if ((FSP_SUCCESS == err) && (ISL29035_CHIP_ID == (device_isl29035_id & ISL29035_DEVICE_ID_MASK)))
  172.     {
  173.         val = (uint8_t)~ISL29035_BOUT_MASK;
  174.         err = isl29035_set_regs(ISL29035_REG_DEVICE_ID, &val, 2, dev);

  175.         if (FSP_SUCCESS != err)
  176.         {
  177.             LOG_E("** isl29035_set_regs API failed **
  178. ");
  179.         }
  180.     }
  181.     else
  182.     {
  183.         /* Failed to get Device ID */
  184.         LOG_E("Error in reading Device ID **
  185. ");
  186.     }
  187.     return err;
  188. }

  189. fsp_err_t isl29035_configure(struct isl29035_dev *dev)
  190. {
  191.     fsp_err_t err         = FSP_SUCCESS;
  192.     uint8_t val;

  193.     /* set command registers to set default attributes */
  194.     val = 0;
  195.     err = isl29035_set_regs(ISL29035_COMMAND_I_REG, &val, 2, dev);

  196.     R_BSP_SoftwareDelay(10, BSP_DELAY_UNITS_MILLISECONDS);
  197.     if (err != FSP_SUCCESS)
  198.         return err;

  199.     err = isl29035_set_regs(ISL29035_COMMAND_II_REG, &val, 2, dev);
  200.     R_BSP_SoftwareDelay(10, BSP_DELAY_UNITS_MILLISECONDS);
  201.     if (err != FSP_SUCCESS)
  202.         return err;

  203.     /* Set operation mode */
  204.     dev->adc_mode = ISL29035_ACTIVE_OPMODE_BITS;
  205.     err = isl29035_set_mode(dev);
  206.     R_BSP_SoftwareDelay(10, BSP_DELAY_UNITS_MILLISECONDS);
  207.     if (err != FSP_SUCCESS)
  208.         return err;

  209.     /* Set the lux range */
  210.     dev->adc_range = ISL29035_LUX_RANGE_BITS;
  211.     err = isl29035_set_range(dev);
  212.     R_BSP_SoftwareDelay(10, BSP_DELAY_UNITS_MILLISECONDS);
  213.     if (err != FSP_SUCCESS)
  214.         return err;

  215.     /* Set ADC resolution */
  216.     dev->adc_res = ISL29035_ADC_RES_BITS;
  217.     err = isl29035_set_res(dev);
  218.     R_BSP_SoftwareDelay(10, BSP_DELAY_UNITS_MILLISECONDS);
  219.     if (err != FSP_SUCCESS)
  220.         return err;

  221.     return err;
  222. }

  223. static float compute_scaling(struct isl29035_dev *dev)
  224. {
  225.     fsp_err_t err         = FSP_SUCCESS;
  226.     uint8_t val, reg_val;
  227.     float scale;
  228.     uint8_t adc_res = 0, lux;
  229.     uint16_t lux_range = 0;

  230.     /*
  231.      * Equation is lux = (Range/2 ^ n) * raw_data
  232.      */

  233.     err = isl29035_get_regs(ISL29035_COMMAND_II_REG, ®_val, 1, dev);
  234.     if (err != FSP_SUCCESS)
  235.         return err;

  236.     //get the ADC range value
  237.     val = (uint8_t)((reg_val & ISL29035_ADC_RES_MASK) >> 2);
  238.     switch (val)
  239.     {
  240.     case 0:
  241.         adc_res = 16;
  242.         break;
  243.     case 1:
  244.         adc_res = 12;
  245.         break;
  246.     case 2:
  247.         adc_res = 8;
  248.         break;
  249.     case 3:
  250.         adc_res = 4;
  251.         break;
  252.     default:
  253.         break;
  254.     }

  255.     //get the ADC resolution value
  256.     lux = (uint8_t)(reg_val & ISL29035_LUX_RANGE_MASK);
  257.     switch (lux)
  258.     {
  259.     case ISL29035_LUX_RANGE_1000:
  260.         lux_range = 1000;
  261.         break;
  262.     case ISL29035_LUX_RANGE_4000:
  263.         lux_range = 4000;
  264.         break;
  265.     case ISL29035_LUX_RANGE_16000:
  266.         lux_range = 16000;
  267.         break;
  268.     case ISL29035_LUX_RANGE_64000:
  269.         lux_range = 64000;
  270.         break;
  271.     default:
  272.         break;
  273.     }

  274.     scale = (float)(lux_range / (pow(2, adc_res)));
  275.     return scale;
  276. }

  277. fsp_err_t isl29035_read_als_data(struct isl29035_dev *dev, double *als_val)
  278. {
  279.     fsp_err_t err         = FSP_SUCCESS;
  280.     uint8_t als_data[2];
  281.     uint16_t als_raw;
  282.     float scale = 0.0;

  283.     err = isl29035_get_regs(ISL29035_DATA_LSB_REG, &als_data[0], 2, dev);
  284.     if (err != FSP_SUCCESS)
  285.         return err;

  286.     als_raw = (uint16_t)((als_data[1] << 8) | als_data[0]);

  287.     //compute scaling factor
  288.     scale = compute_scaling(dev);

  289.     *als_val = (als_raw * scale);

  290.     return err;
  291. }

  292. /*******************************************************************************************************************//**
  293. *  @brief       DeInitialize isl29035
  294. *  @param[IN]   None
  295. *  @retval      None
  296. **********************************************************************************************************************/
  297. void isl29035_deinit(void)
  298. {
  299.     fsp_err_t err     = FSP_SUCCESS;

  300.     /* close open modules */
  301.     err =  hal_i2c_close();

  302.     if (FSP_SUCCESS != err)
  303.     {
  304.         LOG_E("** hal_i2c_close API failed **
  305. ");
  306.     }
  307. }

  1. #define DBG_TAG "sensor.isl29035"
  2. #define DBG_LVL DBG_INFO
  3. #include
  4. #include
  5. #include

  6. #include "hal_data.h"
  7. #include "sensor_renesas_isl29035.h"
  8. #include "isl29035.h"

  9. #define SENSOR_LIGHT_RANGE_MAX (ISL29035_LUX_RANGE)
  10. #define SENSOR_LIGHT_RANGE_MIN (0)

  11. struct isl29035_device
  12. {
  13.     struct rt_i2c_bus_device *i2c;
  14.     rt_uint8_t addr;
  15.     struct isl29035_dev dev;
  16. };
  17. static struct isl29035_device isl29035_device;

  18. static rt_err_t _isl29035_init(struct rt_sensor_intf *intf)
  19. {
  20.     rt_int8_t ret;
  21.     isl29035_device.i2c = rt_i2c_bus_device_find(intf->dev_name);
  22.     if (isl29035_device.i2c == RT_NULL)
  23.     {
  24.         return -RT_ERROR;
  25.     }

  26.     isl29035_device.dev.id = ISL29035_I2C_ADDR;
  27.     isl29035_device.dev.interface = ISL29035_I2C_INTF;

  28.     ret = isl29035_init(&isl29035_device.dev, intf->dev_name);
  29.     if (ret)
  30.     {
  31.         LOG_E("Error %d during initialize hardware, exiting program!
  32. ", ret);
  33.         goto __exit_err;
  34.     }

  35.     ret = isl29035_configure(&isl29035_device.dev);

  36.     if (FSP_SUCCESS != ret)
  37.     {
  38.         /* Sensor init failed, so cleanup the sensor specific initialization */
  39.         LOG_E("** SENSOR ISL29035 CONFIGURATION FAILED **
  40. ");
  41.         isl29035_deinit();
  42.         goto __exit_err;
  43.     }

  44.     return RT_EOK;
  45. __exit_err:
  46.     return -RT_ERROR;
  47. }

  48. static void isl29035_polling_get_data(rt_sensor_t sensor, struct rt_sensor_data *data)
  49. {
  50.     RT_ASSERT(sensor != RT_NULL);
  51.     RT_ASSERT(data != RT_NULL);
  52.     rt_uint8_t ret;
  53.     double als_value; // Ambient Light sensor

  54.     /* Read sensor data */
  55.     ret = isl29035_read_als_data(&isl29035_device.dev, &als_value);
  56.     if (ret)
  57.     {
  58.         LOG_E("Error %d! SENSOR READ DATA FAILED
  59. ", ret);
  60.         goto __exit_err;
  61.     }

  62.     if (sensor->info.type == RT_SENSOR_TYPE_LIGHT)
  63.     {
  64.         data->data.light = als_value;
  65.     }

  66. __exit_err:
  67.     return;
  68. }

  69. static rt_ssize_t isl29035_fetch_data(struct rt_sensor_device *sensor,
  70.                                      struct rt_sensor_data *buf,
  71.                                      rt_size_t len)
  72. {
  73.     RT_ASSERT(buf);

  74.     if (sensor->config.irq_pin.mode == RT_SENSOR_MODE_FETCH_POLLING)
  75.     {
  76.         isl29035_polling_get_data(sensor, buf);
  77.         return 1;
  78.     }
  79.     else
  80.         return 0;
  81. }
  82. static rt_ssize_t isl29035_control(struct rt_sensor_device *sensor, int cmd, void *args)
  83. {
  84.     rt_ssize_t result = RT_EOK;

  85.     return result;
  86. }

  87. static struct rt_sensor_ops sensor_ops =
  88. {
  89.     isl29035_fetch_data,
  90.     isl29035_control
  91. };

  92. int rt_hw_isl29035_init(const char *name, struct rt_sensor_config *cfg)
  93. {
  94.     rt_int8_t result;
  95.     rt_sensor_t sensor_light = RT_NULL;

  96.     /* isl29035 LIGHT sensor register */
  97.     sensor_light = rt_calloc(1, sizeof(struct rt_sensor_device));
  98.     if (sensor_light == RT_NULL)
  99.         return -1;

  100.     sensor_light->info.type       = RT_SENSOR_TYPE_LIGHT;
  101.     sensor_light->info.vendor     = RT_SENSOR_VENDOR_UNKNOWN;
  102.     sensor_light->info.name      = "isl29035";
  103.     sensor_light->info.unit       = RT_SENSOR_UNIT_LUX;
  104.     sensor_light->info.intf_type  = RT_SENSOR_INTF_I2C;
  105.     sensor_light->info.scale.range_max  = SENSOR_LIGHT_RANGE_MAX;
  106.     sensor_light->info.scale.range_min  = SENSOR_LIGHT_RANGE_MIN;
  107.     sensor_light->info.acquire_min = 3000;
  108.     sensor_light->ops = &sensor_ops;
  109.     rt_memcpy(&sensor_light->config, cfg, sizeof(struct rt_sensor_config));

  110.     result = rt_hw_sensor_register(sensor_light,
  111.                                    name,
  112.                                    RT_DEVICE_FLAG_RDONLY,
  113.                                    RT_NULL);
  114.     if (result != RT_EOK)
  115.     {
  116.         LOG_E("device register err code: %d", result);
  117.         goto __exit_err;
  118.     }

  119.     if (RT_EOK != _isl29035_init(&cfg->intf))
  120.         goto __exit_err;

  121.     return RT_EOK;
  122. __exit_err:
  123.     rt_device_unregister(&sensor_light->parent);

  124.     if (sensor_light)
  125.         rt_free(sensor_light);
  126.     return -RT_ERROR;
  127. }


进行端口注册

  1. #include "sensor_renesas_isl29035.h"
  2. int rt_hw_isl29035_port(void)
  3. {
  4.     struct rt_sensor_config cfg;
  5.     cfg.intf.dev_name  = "i2c0";
  6.     rt_hw_isl29035_init("isl29035", &cfg);
  7.     return RT_EOK;
  8. }
  9. INIT_ENV_EXPORT(rt_hw_isl29035_port);
log 中正常打印光照强度值


更多回帖

发帖
×
20
完善资料,
赚取积分