You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by GitBox <gi...@apache.org> on 2017/10/21 00:03:37 UTC

[GitHub] vrahane commented on a change in pull request #630: LP5523: LED Driver

vrahane commented on a change in pull request #630: LP5523: LED Driver
URL: https://github.com/apache/mynewt-core/pull/630#discussion_r146086537
 
 

 ##########
 File path: hw/drivers/lp5523/src/lp5523.c
 ##########
 @@ -0,0 +1,1144 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <defs/error.h>
+#include <sysinit/sysinit.h>
+#include <hal/hal_i2c.h>
+#include <log/log.h>
+#include <stats/stats.h>
+
+#include "lp5523/lp5523.h"
+
+/* Define the stats section and records */
+STATS_SECT_START(lp5523_stat_section)
+    STATS_SECT_ENTRY(read_errors)
+    STATS_SECT_ENTRY(write_errors)
+STATS_SECT_END
+
+/* Define stat names for querying */
+STATS_NAME_START(lp5523_stat_section)
+    STATS_NAME(lp5523_stat_section, read_errors)
+    STATS_NAME(lp5523_stat_section, write_errors)
+STATS_NAME_END(lp5523_stat_section)
+
+/* Global variable used to hold stats data */
+STATS_SECT_DECL(lp5523_stat_section) g_lp5523stats;
+
+#define LOG_MODULE_LP5523    (5523)
+#define LP5523_INFO(...)     LOG_INFO(&_log, LOG_MODULE_LP5523, __VA_ARGS__)
+#define LP5523_ERR(...)      LOG_ERROR(&_log, LOG_MODULE_LP5523, __VA_ARGS__)
+static struct log _log;
+
+/**
+ * Writes a single byte to the specified register
+ *
+ * @param The sensor interface
+ * @param The register address to write to
+ * @param The value to write
+ *
+ * @return 0 on success, non-zero error on failure.
+ */
+int
+lp5523_set_reg(struct sensor_itf *itf, enum lp5523_registers addr,
+    uint8_t value)
+{
+    int rc;
+    uint8_t payload[2] = { addr, value };
+
+    struct hal_i2c_master_data data_struct = {
+        .address = itf->si_addr,
+        .len = 2,
+        .buffer = payload
+    };
+
+    rc = hal_i2c_master_write(itf->si_num, &data_struct,
+                              OS_TICKS_PER_SEC / 10, 1);
+
+    if (rc != 0) {
+        LP5523_ERR("Failed to write to 0x%02X:0x%02X with value 0x%02X\n",
+                       itf->si_addr, addr, value);
+        STATS_INC(g_lp5523stats, read_errors);
+    }
+
+    return rc;
+}
+
+/**
+ * Reads a single byte from the specified register
+ *
+ * @param The sensor interface
+ * @param The register address to read from
+ * @param Pointer to where the register value should be written
+ *
+ * @return 0 on success, non-zero error on failure.
+ */
+int
+lp5523_get_reg(struct sensor_itf *itf, enum lp5523_registers addr,
+    uint8_t *value)
+{
+    int rc;
+
+    struct hal_i2c_master_data data_struct = {
+        .address = itf->si_addr,
+        .len = 1,
+        .buffer = &addr
+    };
+
+    /* Register write */
+    rc = hal_i2c_master_write(itf->si_num, &data_struct,
+                              OS_TICKS_PER_SEC / 10, 0);
+    if (rc != 0) {
+        LP5523_ERR("I2C access failed at address 0x%02X\n", itf->si_addr);
+        STATS_INC(g_lp5523stats, write_errors);
+        return rc;
+    }
+
+    /* Read one byte back */
+    data_struct.buffer = value;
+    rc = hal_i2c_master_read(itf->si_num, &data_struct,
+                             OS_TICKS_PER_SEC / 10, 1);
+
+    if (rc != 0) {
+         LP5523_ERR("Failed to read from 0x%02X:0x%02X\n", itf->si_addr, addr);
+         STATS_INC(g_lp5523stats, read_errors);
+    }
+    return rc;
+}
+
+static int
+lp5523_set_2_regs(struct sensor_itf *itf, enum lp5523_registers addr,
+    uint8_t vals[2])
+{
+    int rc;
+    uint8_t regs[3];
+
+    regs[0] = addr ;
+    regs[1] = vals[0];
+    regs[2] = vals[1];
+
+    struct hal_i2c_master_data data_struct = {
+        .address = itf->si_addr,
+        .len = 3,
+        .buffer = regs
+    };
+
+    rc = hal_i2c_master_write(itf->si_num, &data_struct,
+                              (OS_TICKS_PER_SEC / 5), 1);
+
+    if (rc != 0) {
+        LP5523_ERR("Failed to write to 0x%02X:0x%02X\n", itf->si_addr, regs[0]);
+        STATS_INC(g_lp5523stats, read_errors);
+    }
+    return rc;
+}
+
+/* XXX: Not sure if ai-read is supported, seems to work for reads of length 2 */
+static int
+lp5523_get_2_regs(struct sensor_itf *itf, enum lp5523_registers addr,
+    uint8_t vals[2])
+{
+    int rc;
+    uint8_t addr_b = (uint8_t) addr;
+
+    struct hal_i2c_master_data data_struct = {
+        .address = itf->si_addr,
+        .len = 1,
+        .buffer = &addr_b
+    };
+
+    rc = hal_i2c_master_write(itf->si_num, &data_struct,
+        (OS_TICKS_PER_SEC / 10), 0);
+
+    if (rc != 0) {
+        LP5523_ERR("Failed to write to 0x%02X:0x%02X\n", itf->si_addr, addr_b);
+        STATS_INC(g_lp5523stats, read_errors);
+        return rc;
+    }
+
+    data_struct.len = 2;
+    data_struct.buffer = vals;
+    rc = hal_i2c_master_read(itf->si_num, &data_struct,
+        OS_TICKS_PER_SEC / 5, 1);
+
+    if (rc != 0) {
+         LP5523_ERR("Failed to read from 0x%02X:0x%02X\n", itf->si_addr,
+            addr_b);
+         STATS_INC(g_lp5523stats, read_errors);
+    }
+    return rc;
+}
+
+static void
+lp5523_wait(uint32_t ms)
+{
+    os_time_delay(((ms * OS_TICKS_PER_SEC) / 1000) + 1);
+}
+
+static int
+lp5523_clz(uint8_t val) {
+    uint8_t fs = 0;
+
+    if (val != 0) {
+        while ((val & 1) == 0) {
+            ++fs;
+            val >>= 1;
+        }
+    }
+    return fs;
+}
+
+/**
+ * Writes a section of the specified register
+ *
+ * @param The sensor interface
+ * @param The register address to write to
+ * @param The mask
+ * @param Value to write
+ *
+ * @return 0 on success, non-zero error on failure.
+ */
+int
+lp5523_set_val(struct sensor_itf *itf, enum lp5523_registers addr,
+    uint8_t mask, uint8_t value)
+{
+    int rc;
+    uint8_t reg;
+    uint8_t shift;
+
+    shift = lp5523_clz(mask);
+    value <<= shift;
+
+    if ((value & (~mask)) != 0) {
+        return -1;
+    }
+
+    rc = lp5523_get_reg(itf, addr, &reg);
+    if (rc != 0) {
+        return rc;
+    }
+
+    reg &= ~mask;
+    reg |= mask & value;
+
+    rc = lp5523_set_reg(itf, addr, reg);
+    if (rc != 0) {
+        return rc;
+    }
+    return 0;
+}
+
+/**
+ * Reads a section from the specified register
+ *
+ * @param The sensor interface
+ * @param The register address to read from
+ * @param The mask
+ * @param Pointer to where the value should be written
+ *
+ * @return 0 on success, non-zero error on failure.
+ */
+int
+lp5523_get_val(struct sensor_itf *itf, enum lp5523_registers addr,
+    uint8_t mask, uint8_t *value)
+{
+    int rc;
+    uint8_t reg;
+
+    uint8_t shift;
+
+    shift = lp5523_clz(mask);
+
+    rc = lp5523_get_reg(itf, addr, &reg);
+
+    *value = (reg & mask) >> shift;
+
+    return rc;
+}
+
+/**
+ * Writes 9 bits to 2 registers, useful to write to:
+ * LP5523_BF_OUTPUT_RATIOMETRIC
+ * LP5523_BF_OUTPUT_CONTROL
+ * LP5523_BF_ENG_MAPPING (see lp5523_set_engine_mapping())
+ *
+ * @param The sensor interface
+ * @param The register address to write to (the MSB register)
+ * @param The values to write, only the least significant 9 bits are significant
+ *
+ * @return 0 on success, non-zero error on failure.
+ */
+
+int
+lp5523_set_bitfield(struct sensor_itf *itf, enum lp5523_bitfield_registers addr,
+    uint16_t ops)
+{
+    uint8_t vals[2] = { (ops >> 8) & 0x01, ops & 0xff };
+
+    return lp5523_set_2_regs(itf, addr, vals);
+}
+
+/**
+ * Writes 9 bits to 2 registers, useful to read from:
+ * LP5523_BF_OUTPUT_RATIOMETRIC
+ * LP5523_BF_OUTPUT_CONTROL
+ * LP5523_BF_ENG_MAPPING (see lp5523_set_engine_mapping())
+ *
+ * @param The sensor interface
+ * @param The register address to read from (the MSB register)
+ * @param Pointer to where the register values should be written
+ *
+ * @return 0 on success, non-zero error on failure.
+ */
+
+int
+lp5523_get_bitfield(struct sensor_itf *itf, enum lp5523_bitfield_registers addr,
+    uint16_t* ops)
+{
+    int rc;
+    uint8_t vals[2];
+
+    rc = lp5523_get_2_regs(itf, addr, vals);
+
+    *ops = ((vals[0] & 0x01) << 8) | vals[1];
+
+    return rc;
+}
+
+/**
+ * Writes to a register with an output-based address offset,
+ * useful to write to:
+ * LP5523_OP_CONTROL
+ * LP5523_OP_PWM
+ * LP5523_OP_CURRENT_CONTROL
+ *
+ * @param The sensor interface
+ * @param The register address to write to (the MSB register)
+ * @param Value to write
+ *
+ * @return 0 on success, non-zero error on failure.
+ */
+int
+lp5523_set_output_reg(struct sensor_itf *itf, enum lp5523_output_registers addr,
+    uint8_t op, uint8_t value)
+{
+    --op;
+    return (op > 8) ? -1 : lp5523_set_reg(itf, addr + op, value);
+}
+
+/**
+ * Reads from a register with an output-based address offset,
+ * useful to read from:
+ * LP5523_OP_CONTROL
+ * LP5523_OP_PWM
+ * LP5523_OP_CURRENT_CONTROL
+ *
+ * @param The sensor interface
+ * @param The register address to read from (the MSB register)
+ * @param Pointer to where the register values should be written
+ *
+ * @return 0 on success, non-zero error on failure.
+ */
+int
+lp5523_get_outout_reg(struct sensor_itf *itf, enum lp5523_output_registers addr,
+    uint8_t op, uint8_t *value)
+{
+    --op;
 
 Review comment:
   One argument is not commented for here: "op". What if op is 0 ? Is that possible ?

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services