mirror of
https://github.com/eried/portapack-mayhem.git
synced 2025-08-06 13:44:26 -04:00
I2C device manager (#2282)
* message on dev list change * dc detect * added sht3x sensor. * separete environment data from light * max17055 moved to i2c dev * sht fix, goterror detection fix * fix ext sensor app display for a lot of devices. * added bh1750 driver * autoscan on main view * added devlist mutex * better timing * fix h2 sw8 on poweron by usb
This commit is contained in:
parent
d4edb5f5f9
commit
83b65ba6ce
35 changed files with 1459 additions and 472 deletions
104
firmware/common/i2cdevmanager.hpp
Normal file
104
firmware/common/i2cdevmanager.hpp
Normal file
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* Copyright (C) 2024 HTotoo.
|
||||
*
|
||||
* This file is part of PortaPack.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __I2CDEVMANAGER_H__
|
||||
#define __I2CDEVMANAGER_H__
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include "ch.h"
|
||||
#include "portapack.hpp"
|
||||
#include "i2c_pp.hpp"
|
||||
#include "i2cdevlist.hpp"
|
||||
#include "event_m0.hpp"
|
||||
|
||||
#define i2cbus portapack::i2c0
|
||||
|
||||
extern I2C portapack::i2c0;
|
||||
|
||||
namespace i2cdev {
|
||||
|
||||
// The device class. You'll derive your from this. Override init() and update();
|
||||
class I2cDev {
|
||||
public:
|
||||
virtual ~I2cDev(){};
|
||||
virtual bool init(uint8_t addr); // returns true if it is that that device we are looking for.
|
||||
virtual void update() = 0; // override this, and you'll be able to query your device and broadcast the result to the system
|
||||
|
||||
void set_update_interval(uint8_t interval); // sets the device's update interval in sec. if you change it, don't forget to change back to it's original value after you finished!
|
||||
uint8_t get_update_interval(); // gets the device's update interval in sec
|
||||
|
||||
bool i2c_read(uint8_t* reg, uint8_t reg_size, uint8_t* data, uint8_t bytes); // if want to read without register addr, just set reg_size to 0. this way can read 8, or 16 or 32 bit registers too. reg_size in bytes! returns true on succes. handles the errcnt automatically!
|
||||
bool i2c_write(uint8_t* reg, uint8_t reg_size, uint8_t* data, uint8_t bytes); // if want to write without register addr, just set reg_size to 0. this way can read 8, or 16 or 32 bit registers too. reg_size in bytes! returns true on succes. handles the errcnt automatically!
|
||||
|
||||
// helpers for easier i2c communication
|
||||
uint8_t read8_1(uint8_t reg);
|
||||
bool write8_1(uint8_t reg, uint8_t data);
|
||||
uint16_t read16_1(uint8_t reg);
|
||||
int16_t readS16_1(uint8_t reg);
|
||||
uint16_t read16_LE_1(uint8_t reg);
|
||||
int16_t readS16_LE_1(uint8_t reg);
|
||||
uint32_t read24_1(uint8_t reg);
|
||||
|
||||
bool need_del = false; // device can self destruct, and re-init when new scan discovers it
|
||||
I2C_DEVMDL model = I2CDEVMDL_NOTSET; // overwrite it in the init()!!!
|
||||
uint8_t query_interval = 5; // in seconds. can be overriden in init() if necessary
|
||||
protected:
|
||||
void got_error(); // i2c communication will call this when communication was not ok. you can call it from any part of your code too.
|
||||
void got_success(); // i2c communication will call this when the communication was ok. you can call it from any part of your code too.
|
||||
|
||||
uint8_t addr = 0; // some devices can have different addresses, so we store what was it wound with
|
||||
uint8_t errcnt = 0; // error count during communication. if it reaches a threshold set need_del to remove itself from the device list
|
||||
};
|
||||
|
||||
// store for the devices. may not have a driver if not supported
|
||||
class I2DevListElement {
|
||||
public:
|
||||
uint8_t addr = 0; // i2c addr of the device
|
||||
std::unique_ptr<I2cDev> dev = nullptr; // device driver if any
|
||||
};
|
||||
|
||||
class I2CDevManager {
|
||||
public:
|
||||
static void init(); // creates the thread, and sets an one time full scan
|
||||
static void manual_scan(); // it'll init a forced device scan in the thread's next cycle. (1sec max)
|
||||
static void set_autoscan_interval(uint16_t interval); // 0 no auto scan, other values: seconds
|
||||
static uint16_t get_autoscan_interval();
|
||||
static I2cDev* get_dev_by_addr(uint8_t addr); // caller function needs to cast to the specific device!
|
||||
static I2cDev* get_dev_by_model(I2C_DEVMDL model); // caller function needs to cast to the specific device!
|
||||
static std::vector<I2C_DEVMDL> get_dev_list_by_model(); // returns the currently discovered
|
||||
static std::vector<uint8_t> get_gev_list_by_addr(); // returns the currently discovered
|
||||
|
||||
private:
|
||||
static uint16_t scan_interval;
|
||||
static bool force_scan; // if set to true, on hte next run it'll do an i2c scan, ONCE
|
||||
static std::vector<I2DevListElement> devlist;
|
||||
|
||||
static bool found(uint8_t addr); // returns true on any new device. also initializes the driver if there is a suitable one
|
||||
static bool scan(); // return true on any change (delete or found new)
|
||||
static void create_thread();
|
||||
static msg_t timer_fn(void* arg);
|
||||
static Thread* thread;
|
||||
static Mutex mutex_list;
|
||||
};
|
||||
}; // namespace i2cdev
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue