From 7d6a4577db016644061778fe035a3b931b73f267 Mon Sep 17 00:00:00 2001
From: Uros Majstorovic <majstor@majstor.org>
Date: Thu, 12 Sep 2024 15:50:45 +0200
Subject: prox sensor driver initial import

---
 fw/fe310/eos/dev/apds9151.c | 119 ++++++++++++++++++++++++++++++++++++++++++++
 fw/fe310/eos/dev/apds9151.h |  32 ++++++++++++
 2 files changed, 151 insertions(+)
 create mode 100644 fw/fe310/eos/dev/apds9151.c
 create mode 100644 fw/fe310/eos/dev/apds9151.h

(limited to 'fw/fe310')

diff --git a/fw/fe310/eos/dev/apds9151.c b/fw/fe310/eos/dev/apds9151.c
new file mode 100644
index 0000000..9e0237e
--- /dev/null
+++ b/fw/fe310/eos/dev/apds9151.c
@@ -0,0 +1,119 @@
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "eos.h"
+#include "soc/i2c.h"
+
+#include "apds9151.h"
+
+#define APDS9151_ADDR                   0x52
+
+static int reg_read8(uint8_t reg, uint8_t *data) {
+    int rv;
+
+    rv = eos_i2c_read8(APDS9151_ADDR, reg, data, 1);
+    return rv;
+}
+
+static int reg_write8(uint8_t reg, uint8_t data) {
+    int rv;
+
+    rv = eos_i2c_write8(APDS9151_ADDR, reg, &data, 1);
+    return rv;
+}
+
+static int reg_read16(uint8_t reg, uint16_t *data) {
+    int rv;
+    uint8_t b[2];
+
+    rv = eos_i2c_read8(APDS9151_ADDR, reg, b, 2);
+    if (rv) return rv;
+
+    *data = \
+        ((uint16_t)b[0]) | \
+        ((uint16_t)b[1] << 8);
+    return EOS_OK;
+}
+
+static int reg_write16(uint8_t reg, uint16_t data) {
+    int rv;
+    uint8_t b[2];
+
+    b[0] = data;
+    b[1] = data >> 8;
+    rv = eos_i2c_write8(APDS9151_ADDR, reg, b, 2);
+    if (rv) return rv;
+
+    return EOS_OK;
+}
+
+static int reg_read32(uint8_t reg, uint32_t *data) {
+    int rv;
+    uint8_t b[3];
+
+    rv = eos_i2c_read8(APDS9151_ADDR, reg, b, 3);
+    if (rv) return rv;
+
+    *data = \
+        ((uint32_t)b[0]) | \
+        ((uint32_t)b[1] << 8) | \
+        ((uint32_t)b[2] << 16);
+    return EOS_OK;
+}
+
+static int reg_write32(uint8_t reg, uint32_t data) {
+    int rv;
+    uint8_t b[3];
+
+    b[0] = data;
+    b[1] = data >> 8;
+    b[2] = data >> 16;
+    rv = eos_i2c_write8(APDS9151_ADDR, reg, b, 3);
+    if (rv) return rv;
+
+    return EOS_OK;
+}
+
+int eos_apds9151_reg_read(uint8_t reg, void *data) {
+    int rv = EOS_OK;
+
+    switch (reg & (~APDS9151_REG_MASK)) {
+        case APDS9151_REG_SIZE_8: {
+            rv = reg_read8(reg & APDS9151_REG_MASK, (uint8_t *)data);
+            break;
+        }
+        case APDS9151_REG_SIZE_16: {
+            rv = reg_read16(reg & APDS9151_REG_MASK, (uint16_t *)data);
+            break;
+        }
+        case APDS9151_REG_SIZE_32: {
+            rv = reg_read32(reg & APDS9151_REG_MASK, (uint32_t *)data);
+            break;
+        }
+        default: return EOS_ERR;
+    }
+
+    return rv;
+}
+
+int eos_apds9151_reg_write(uint8_t reg, uint32_t data) {
+    int rv = EOS_OK;
+
+    switch (reg & (~APDS9151_REG_MASK)) {
+        case APDS9151_REG_SIZE_8: {
+            rv = reg_write8(reg & APDS9151_REG_MASK, (uint8_t)data);
+            break;
+        }
+        case APDS9151_REG_SIZE_16: {
+            rv = reg_write16(reg & APDS9151_REG_MASK, (uint16_t)data);
+            break;
+        }
+        case APDS9151_REG_SIZE_32: {
+            rv = reg_write32(reg & APDS9151_REG_MASK, (uint32_t)data);
+            break;
+        }
+        default: return EOS_ERR;
+    }
+
+    return rv;
+}
diff --git a/fw/fe310/eos/dev/apds9151.h b/fw/fe310/eos/dev/apds9151.h
new file mode 100644
index 0000000..2827dfe
--- /dev/null
+++ b/fw/fe310/eos/dev/apds9151.h
@@ -0,0 +1,32 @@
+#include <stdint.h>
+
+#define APDS9151_REG_SIZE_8             0x00
+#define APDS9151_REG_SIZE_16            0x40
+#define APDS9151_REG_SIZE_32            0x80
+
+#define APDS9151_REG_MAIN_CTRL          (0x00 | APDS9151_REG_SIZE_8)
+#define APDS9151_REG_PS_LED             (0x01 | APDS9151_REG_SIZE_8)
+#define APDS9151_REG_PS_PULSES          (0x02 | APDS9151_REG_SIZE_8)
+#define APDS9151_REG_PS_MEAS_RATE       (0x03 | APDS9151_REG_SIZE_8)
+#define APDS9151_REG_LS_MEAS_RATE       (0x04 | APDS9151_REG_SIZE_8)
+#define APDS9151_REG_LS_GAIN            (0x05 | APDS9151_REG_SIZE_8)
+#define APDS9151_REG_PART_ID            (0x06 | APDS9151_REG_SIZE_8)
+#define APDS9151_REG_MAIN_STATUS        (0x07 | APDS9151_REG_SIZE_8)
+#define APDS9151_REG_PS_DATA            (0x08 | APDS9151_REG_SIZE_16)
+#define APDS9151_REG_LS_DATA_IR         (0x0A | APDS9151_REG_SIZE_32)
+#define APDS9151_REG_LS_DATA_GREEN      (0x0D | APDS9151_REG_SIZE_32)
+#define APDS9151_REG_LS_DATA_BLUE       (0x10 | APDS9151_REG_SIZE_32)
+#define APDS9151_REG_LS_DATA_RED        (0x13 | APDS9151_REG_SIZE_32)
+#define APDS9151_REG_INT_CFG            (0x19 | APDS9151_REG_SIZE_8)
+#define APDS9151_REG_INT_PST            (0x1A | APDS9151_REG_SIZE_8)
+#define APDS9151_REG_PS_THRES_UP        (0x1B | APDS9151_REG_SIZE_16)
+#define APDS9151_REG_PS_THRES_LOW       (0x1D | APDS9151_REG_SIZE_16)
+#define APDS9151_REG_PS_CAN             (0x1F | APDS9151_REG_SIZE_16)
+#define APDS9151_REG_LS_THRES_UP        (0x21 | APDS9151_REG_SIZE_32)
+#define APDS9151_REG_LS_THRES_LOW       (0x24 | APDS9151_REG_SIZE_32)
+#define APDS9151_REG_LS_THRES_VAR       (0x27 | APDS9151_REG_SIZE_8)
+
+#define APDS9151_REG_MASK               0x3F
+
+int eos_apds9151_reg_read(uint8_t reg, void *data);
+int eos_apds9151_reg_write(uint8_t reg, uint32_t data);
\ No newline at end of file
-- 
cgit v1.2.3