Code formatted, minor fixes (#466)
This commit is contained in:
parent
8a474d749d
commit
5fa48d0298
28 changed files with 623 additions and 608 deletions
|
@ -292,6 +292,7 @@ size_t spi_transfer(uint8_t bus, const void *out_data, void *in_data, size_t len
|
|||
static inline void spi_set_command(uint8_t bus, uint8_t bits, uint16_t data)
|
||||
{
|
||||
if (!bits) return;
|
||||
|
||||
SPI(bus).USER0 |= SPI_USER0_COMMAND; //enable COMMAND function in SPI module
|
||||
uint16_t command = data << (16 - bits); //align command data to high bits
|
||||
command = ((command >> 8) & 0xff) | ((command << 8) & 0xff00); //swap byte order
|
||||
|
@ -317,6 +318,7 @@ static inline void spi_set_command(uint8_t bus,uint8_t bits, uint16_t data)
|
|||
static inline void spi_set_address(uint8_t bus, uint8_t bits, uint32_t data)
|
||||
{
|
||||
if (!bits) return;
|
||||
|
||||
SPI(bus).USER0 |= SPI_USER0_ADDR; //enable ADDRess function in SPI module
|
||||
SPI(bus).ADDR = data << (32 - bits); //align address data to high bits
|
||||
SPI(bus).USER1 = SET_FIELD(SPI(bus).USER1, SPI_USER1_ADDR_BITLEN, --bits);
|
||||
|
@ -340,7 +342,8 @@ static inline void spi_set_address(uint8_t bus,uint8_t bits, uint32_t data)
|
|||
static inline void spi_set_dummy_bits(uint8_t bus, uint8_t bits, bool pos)
|
||||
{
|
||||
if (!bits) return;
|
||||
if(pos) { SPI(bus).USER0 |= SPI_USER0_MISO; } // Dummy bit will be between Dout and Din data if set
|
||||
if (pos)
|
||||
SPI(bus).USER0 |= SPI_USER0_MISO; // Dummy bit will be between Dout and Din data if set
|
||||
SPI(bus).USER0 |= SPI_USER0_DUMMY; //enable dummy bits
|
||||
SPI(bus).USER1 = SET_FIELD(SPI(bus).USER1, SPI_USER1_DUMMY_CYCLELEN, --bits);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Part of esp-open-rtos
|
||||
* Copyright (C) 2016 Ruslan V. Uss <unclerus@gmail.com>,
|
||||
* Pavel Merlyakov <merzlyakovpavel@gmail.com>
|
||||
* Pavel Merzlyakov <merzlyakovpavel@gmail.com>
|
||||
* BSD Licensed as described in the file LICENSE
|
||||
*/
|
||||
#ifndef EXTRAS_DS1302_H_
|
||||
|
|
|
@ -78,7 +78,8 @@ void ds1307_get_time(i2c_dev_t* dev, struct tm *time)
|
|||
if (buf[2] & PM_BIT)
|
||||
time->tm_hour += 12;
|
||||
}
|
||||
else time->tm_hour = bcd2dec(buf[2] & HOUR24_MASK);
|
||||
else
|
||||
time->tm_hour = bcd2dec(buf[2] & HOUR24_MASK);
|
||||
time->tm_wday = bcd2dec(buf[3]) - 1;
|
||||
time->tm_mday = bcd2dec(buf[4]);
|
||||
time->tm_mon = bcd2dec(buf[5]) - 1;
|
||||
|
@ -132,7 +133,9 @@ void ds1307_set_output(i2c_dev_t* dev, bool value)
|
|||
|
||||
int ds1307_read_ram(i2c_dev_t *dev, uint8_t offset, uint8_t *buf, uint8_t len)
|
||||
{
|
||||
if (offset + len > RAM_SIZE) return false;
|
||||
if (offset + len > RAM_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
uint8_t reg = RAM_REG + offset;
|
||||
|
||||
return i2c_slave_read(dev->bus, dev->addr, ®, buf, len);
|
||||
|
@ -140,7 +143,9 @@ int ds1307_read_ram(i2c_dev_t* dev, uint8_t offset, uint8_t *buf, uint8_t len)
|
|||
|
||||
int ds1307_write_ram(i2c_dev_t *dev, uint8_t offset, uint8_t *buf, uint8_t len)
|
||||
{
|
||||
if (offset + len > RAM_SIZE) return false;
|
||||
if (offset + len > RAM_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
uint8_t reg = RAM_REG + offset;
|
||||
|
||||
return i2c_slave_write(dev->bus, dev->addr, ®, buf, len);
|
||||
|
|
|
@ -18,10 +18,11 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#define DS1307_ADDR 0x68
|
||||
|
||||
/**
|
||||
* Squarewave frequency
|
||||
*/
|
||||
typedef enum _ds1307_squarewave_freq_t
|
||||
typedef enum
|
||||
{
|
||||
DS1307_1HZ = 0, //!< 1 Hz
|
||||
DS1307_4096HZ, //!< 4096 Hz
|
||||
|
|
|
@ -104,7 +104,7 @@ hd44780_t lcd = {
|
|||
hd44780_t lcd = {
|
||||
.addr = ADDR,
|
||||
.font = HD44780_FONT_5X8,
|
||||
.lines = 2,
|
||||
.lines = 4,
|
||||
.pins = {
|
||||
.rs = 0,
|
||||
.e = 2,
|
||||
|
|
|
@ -30,7 +30,7 @@ static int _wireWriteRegister (const i2c_dev_t* dev, uint8_t reg, uint16_t value
|
|||
static int _wireReadRegister(const i2c_dev_t *dev, uint8_t reg, uint16_t *value)
|
||||
{
|
||||
uint8_t d[] = { 0, 0 };
|
||||
int error = i2c_slave_read(dev->bus, dev->addr, ®, d, sizeof(d))
|
||||
int error = i2c_slave_read(dev->bus, dev->addr, ®, d, sizeof(d));
|
||||
debug("Data read from bus %u at %02X: %02X+%04X\n", dev->bus, dev->addr, reg, *value);
|
||||
*value = d[1] | (d[0] << 8);
|
||||
return error;
|
||||
|
@ -53,14 +53,16 @@ int ina3221_sync(ina3221_t *dev)
|
|||
//////////////////////// Sync config register
|
||||
if ((err = _wireReadRegister(&dev->i2c_dev, INA3221_REG_CONFIG, &ptr_data))) // Read config
|
||||
return err;
|
||||
if( ptr_data != dev->config.config_register) {
|
||||
if (ptr_data != dev->config.config_register)
|
||||
{
|
||||
if ((err = _wireWriteRegister(&dev->i2c_dev, INA3221_REG_CONFIG, dev->config.config_register))) // Update config
|
||||
return err;
|
||||
}
|
||||
//////////////////////// Sync mask register config
|
||||
if ((err = _wireReadRegister(&dev->i2c_dev, INA3221_REG_MASK, &ptr_data))) // Read mask
|
||||
return err;
|
||||
if( (ptr_data & INA3221_MASK_CONFIG) != (dev->mask.mask_register & INA3221_MASK_CONFIG)) {
|
||||
if ((ptr_data & INA3221_MASK_CONFIG) != (dev->mask.mask_register & INA3221_MASK_CONFIG))
|
||||
{
|
||||
if ((err = _wireWriteRegister(&dev->i2c_dev, INA3221_REG_MASK, dev->mask.mask_register & INA3221_MASK_CONFIG))) // Update config
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -19,14 +19,14 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "i2c/i2c.h"
|
||||
#include <i2c/i2c.h>
|
||||
|
||||
#define INA3221_ADDR_0 (0x40) // A0 to GND
|
||||
#define INA3221_ADDR_1 (0x41) // A0 to Vs+
|
||||
#define INA3221_ADDR_2 (0x42) // A0 to SDA
|
||||
#define INA3221_ADDR_3 (0x43) // A0 to SCL
|
||||
#define INA3221_ADDR_0 (0x40) ///< A0 to GND
|
||||
#define INA3221_ADDR_1 (0x41) ///< A0 to Vs+
|
||||
#define INA3221_ADDR_2 (0x42) ///< A0 to SDA
|
||||
#define INA3221_ADDR_3 (0x43) ///< A0 to SCL
|
||||
|
||||
#define BUS_NUMBER 3 //Number of shunt available
|
||||
#define BUS_NUMBER 3 ///< Number of shunt available
|
||||
|
||||
#define INA3221_REG_CONFIG (0x00)
|
||||
#define INA3221_REG_SHUNTVOLTAGE_1 (0x01)
|
||||
|
@ -39,7 +39,7 @@ extern "C" {
|
|||
#define INA3221_REG_VALID_POWER_UPPER_LIMIT (0x10)
|
||||
#define INA3221_REG_VALID_POWER_LOWER_LIMIT (0x11)
|
||||
|
||||
/*
|
||||
/**
|
||||
* Default register after reset
|
||||
*/
|
||||
#define INA3221_DEFAULT_CONFIG (0x7127)
|
||||
|
@ -48,11 +48,12 @@ extern "C" {
|
|||
#define INA3221_DEFAULT_POWER_LOWER_LIMIT (0x2328) //9V
|
||||
|
||||
#define INA3221_MASK_CONFIG (0x7C00)
|
||||
/*
|
||||
* Numbrer of samples
|
||||
|
||||
/**
|
||||
* Number of samples
|
||||
*/
|
||||
typedef enum {
|
||||
INA3221_AVG_1 = 0, //Default
|
||||
INA3221_AVG_1 = 0, ///< Default
|
||||
INA3221_AVG_4,
|
||||
INA3221_AVG_16,
|
||||
INA3221_AVG_64,
|
||||
|
@ -62,7 +63,7 @@ typedef enum {
|
|||
INA3221_AVG_1024,
|
||||
} ina3221_avg_t;
|
||||
|
||||
/*
|
||||
/**
|
||||
* Channel selection list
|
||||
*/
|
||||
typedef enum {
|
||||
|
@ -71,7 +72,7 @@ typedef enum {
|
|||
CHANNEL_3,
|
||||
} ina3221_channel_t;
|
||||
|
||||
/*
|
||||
/**
|
||||
* Conversion time in us
|
||||
*/
|
||||
typedef enum {
|
||||
|
@ -79,63 +80,63 @@ typedef enum {
|
|||
INA3221_CT_204,
|
||||
INA3221_CT_332,
|
||||
INA3221_CT_588,
|
||||
INA3221_CT_1100, //Default
|
||||
INA3221_CT_1100, ///< Default
|
||||
INA3221_CT_2116,
|
||||
INA3221_CT_4156,
|
||||
INA3221_CT_8244,
|
||||
} ina3221_ct_t;
|
||||
|
||||
/*
|
||||
/**
|
||||
* Config description register
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
uint16_t esht : 1; // Enable/Disable shunt measure // LSB
|
||||
uint16_t ebus : 1; // Enable/Disable bus measure
|
||||
uint16_t mode : 1; // Single shot measure or continious mode
|
||||
uint16_t vsht : 3; // Shunt voltage conversion time
|
||||
uint16_t vbus : 3; // Bus voltage conversion time
|
||||
uint16_t avg : 3; // number of sample collected and averaged together
|
||||
uint16_t ch3 : 1; // Enable/Disable channel 3
|
||||
uint16_t ch2 : 1; // Enable/Disable channel 2
|
||||
uint16_t ch1 : 1; // Enable/Disable channel 1
|
||||
uint16_t rst : 1; //Set this bit to 1 to reset device // MSB
|
||||
uint16_t esht : 1; ///< Enable/Disable shunt measure // LSB
|
||||
uint16_t ebus : 1; ///< Enable/Disable bus measure
|
||||
uint16_t mode : 1; ///< Single shot measure or continious mode
|
||||
uint16_t vsht : 3; ///< Shunt voltage conversion time
|
||||
uint16_t vbus : 3; ///< Bus voltage conversion time
|
||||
uint16_t avg : 3; ///< number of sample collected and averaged together
|
||||
uint16_t ch3 : 1; ///< Enable/Disable channel 3
|
||||
uint16_t ch2 : 1; ///< Enable/Disable channel 2
|
||||
uint16_t ch1 : 1; ///< Enable/Disable channel 1
|
||||
uint16_t rst : 1; ///< Set this bit to 1 to reset device // MSB
|
||||
};
|
||||
uint16_t config_register;
|
||||
} ina3221_config_t;
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* Mask/enable description register
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
uint16_t cvrf : 1 ; // Conversion ready flag (1: ready) // LSB
|
||||
uint16_t tcf : 1 ; // Timing control flag
|
||||
uint16_t pvf : 1 ; // Power valid flag
|
||||
uint16_t wf : 3 ; // Warning alert flag (Read mask to clear) (order : Channel1:channel2:channel3)
|
||||
uint16_t sf : 1 ; // Sum alert flag (Read mask to clear)
|
||||
uint16_t cf : 3 ; // Critical alert flag (Read mask to clear) (order : Channel1:channel2:channel3)
|
||||
uint16_t cen : 1 ; // Critical alert latch (1:enable)
|
||||
uint16_t wen : 1 ; // Warning alert latch (1:enable)
|
||||
uint16_t scc3 : 1 ; // channel 3 sum (1:enable)
|
||||
uint16_t scc2 : 1 ; // channel 2 sum (1:enable)
|
||||
uint16_t scc1 : 1 ; // channel 1 sum (1:enable)
|
||||
uint16_t : 1 ; //Reserved //MSB
|
||||
uint16_t cvrf : 1; ///< Conversion ready flag (1: ready) // LSB
|
||||
uint16_t tcf : 1; ///< Timing control flag
|
||||
uint16_t pvf : 1; ///< Power valid flag
|
||||
uint16_t wf : 3; ///< Warning alert flag (Read mask to clear) (order : Channel1:channel2:channel3)
|
||||
uint16_t sf : 1; ///< Sum alert flag (Read mask to clear)
|
||||
uint16_t cf : 3; ///< Critical alert flag (Read mask to clear) (order : Channel1:channel2:channel3)
|
||||
uint16_t cen : 1; ///< Critical alert latch (1:enable)
|
||||
uint16_t wen : 1; ///< Warning alert latch (1:enable)
|
||||
uint16_t scc3 : 1; ///< channel 3 sum (1:enable)
|
||||
uint16_t scc2 : 1; ///< channel 2 sum (1:enable)
|
||||
uint16_t scc1 : 1; ///< channel 1 sum (1:enable)
|
||||
uint16_t : 1; ///< Reserved //MSB
|
||||
};
|
||||
uint16_t mask_register;
|
||||
} ina3221_mask_t;
|
||||
|
||||
/*
|
||||
/**
|
||||
* Device description
|
||||
*/
|
||||
typedef struct {
|
||||
const i2c_dev_t i2c_dev; // ina3221 I2C address
|
||||
const uint16_t shunt[BUS_NUMBER]; //Memory of shunt value (mOhm)
|
||||
ina3221_config_t config; //Memory of ina3221 config
|
||||
ina3221_mask_t mask; //Memory of mask_config
|
||||
const i2c_dev_t i2c_dev; ///< ina3221 I2C address
|
||||
const uint16_t shunt[BUS_NUMBER]; ///< Memory of shunt value (mOhm)
|
||||
ina3221_config_t config; ///< Memory of ina3221 config
|
||||
ina3221_mask_t mask; ///< Memory of mask_config
|
||||
} ina3221_t;
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Driver for SSD1306 OLED LCD
|
||||
# Driver for SSD1306/SH1106 OLED LCD
|
||||
|
||||
This driver is written for usage with the ESP8266 and FreeRTOS ([esp-open-rtos](https://github.com/SuperHouse/esp-open-rtos)).
|
||||
|
||||
|
@ -11,34 +11,38 @@ This driver is written for usage with the ESP8266 and FreeRTOS ([esp-open-rtos](
|
|||
|
||||
## Supported connection interfaces
|
||||
|
||||
Currently supported two of them: I2C and SPI4.
|
||||
I2C, SPI3 and SPI4.
|
||||
|
||||
## Usage
|
||||
|
||||
If Reset pin is accesible in your display module, connect it to the RESET pin of ESP8266.
|
||||
If you don't do this, display RAM may be glitchy after the power lost/restore.
|
||||
If you don't, display RAM could be glitchy after the power cycle.
|
||||
|
||||
### I2C protocol
|
||||
|
||||
Before using the SSD1306 LCD module the function `i2c_init(SCL_PIN, SDA_PIN)` needs to be
|
||||
called to setup the I2C interface and then you must call `ssd1306_init()`.
|
||||
Before using the OLED module you need to call the function `i2c_init(BUS, SCL_PIN, SDA_PIN, I2C_FREQ_400K)`
|
||||
to configure the I2C interface and then you should call `ssd1306_init()`.
|
||||
|
||||
#### Example
|
||||
|
||||
```C
|
||||
#define SCL_PIN 5
|
||||
#define SDA_PIN 4
|
||||
#define I2C_BUS 0
|
||||
...
|
||||
|
||||
static const ssd1306_t device = {
|
||||
.protocol = SSD1306_PROTO_I2C,
|
||||
.screen = SSD1306_SCREEN, // or SH1106_SCREEN
|
||||
.i2c_dev.bus = I2C_BUS,
|
||||
.i2c_dev.addr = SSD1306_I2C_ADDR_0,
|
||||
.width = 128,
|
||||
.height = 64
|
||||
};
|
||||
|
||||
...
|
||||
|
||||
i2c_init(SCL_PIN, SDA_PIN);
|
||||
i2c_init(I2C_BUS, SCL_PIN, SDA_PIN, I2C_FREQ_400K);
|
||||
|
||||
if (ssd1306_init(&device)) {
|
||||
// An error occured, while performing SSD1306 init (E.g device not found etc.)
|
||||
|
@ -47,14 +51,15 @@ if (ssd1306_init(&device)) {
|
|||
// rest of the code
|
||||
```
|
||||
|
||||
### SPI4 protocol
|
||||
### SPI3 and SPI4 protocols
|
||||
|
||||
This protocol MUCH faster than I2C but uses 2 additional GPIO pins (beside of HSPI CLK
|
||||
and HSPI MOSI): Data/Command pin and Chip Select pin.
|
||||
These protocols are MUCH faster than I2C, but use 2 additional GPIO pins
|
||||
(besides the **HSPI CLK** and **HSPI MOSI**): **Chip Select** and **Data/Command** (in case of SPI4).
|
||||
|
||||
No additional function calls are required before `ssd1306_init()`.
|
||||
|
||||
#### Example
|
||||
|
||||
#### SPI4 Example
|
||||
|
||||
```C
|
||||
#define CS_PIN 5
|
||||
|
@ -64,6 +69,7 @@ No additional function calls are required before `ssd1306_init()`.
|
|||
|
||||
static const ssd1306_t device = {
|
||||
.protocol = SSD1306_PROTO_SPI4,
|
||||
.screen = SSD1306_SCREEN,
|
||||
.cs_pin = CS_PIN,
|
||||
.dc_pin = DC_PIN,
|
||||
.width = 128,
|
||||
|
@ -78,3 +84,27 @@ if (ssd1306_init(&device)) {
|
|||
|
||||
// rest of the code
|
||||
```
|
||||
|
||||
#### SPI3 example
|
||||
```C
|
||||
|
||||
#define CS_PIN 5
|
||||
|
||||
...
|
||||
|
||||
static const ssd1306_t device = {
|
||||
.protocol = SSD1306_PROTO_SPI3,
|
||||
.screen = SSD1306_SCREEN,
|
||||
.cs_pin = CS_PIN,
|
||||
.width = 128,
|
||||
.height = 64
|
||||
};
|
||||
|
||||
...
|
||||
|
||||
if (ssd1306_init(&device)) {
|
||||
// An error occured, while performing SSD1306 init
|
||||
}
|
||||
|
||||
// rest of the code
|
||||
```
|
||||
|
|
|
@ -85,7 +85,6 @@
|
|||
#define abs(x) ((x)<0 ? -(x) : (x))
|
||||
#define swap(x, y) do { typeof(x) temp##x##y = x; x = y; y = temp##x##y; } while (0)
|
||||
|
||||
|
||||
#if (SSD1306_I2C_SUPPORT)
|
||||
static int inline i2c_send(const ssd1306_t *dev, uint8_t reg, uint8_t* data, uint8_t len)
|
||||
{
|
||||
|
@ -221,8 +220,10 @@ int ssd1306_init(const ssd1306_t *dev)
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
static int sh1106_go_coordinate(const ssd1306_t *dev, uint8_t x, uint8_t y) {
|
||||
if (x >= dev->width || y >= (dev->height/8)) return -EINVAL;
|
||||
static int sh1106_go_coordinate(const ssd1306_t *dev, uint8_t x, uint8_t y)
|
||||
{
|
||||
if (x >= dev->width || y >= (dev->height / 8))
|
||||
return -EINVAL;
|
||||
int err = 0;
|
||||
x += 2; //offset : panel is 128 ; RAM is 132 for sh1106
|
||||
if ((err = ssd1306_command(dev, SH1106_SET_PAGE_ADDRESS + y))) // Set row
|
||||
|
@ -240,8 +241,7 @@ int ssd1306_load_frame_buffer(const ssd1306_t *dev, uint8_t buf[])
|
|||
uint8_t tab[16] = { 0 };
|
||||
#endif
|
||||
size_t len = dev->width * dev->height / 8;
|
||||
if(dev->screen == SSD1306_SCREEN)
|
||||
{
|
||||
if (dev->screen == SSD1306_SCREEN) {
|
||||
ssd1306_set_column_addr(dev, 0, dev->width - 1);
|
||||
ssd1306_set_page_addr(dev, 0, dev->height / 8 - 1);
|
||||
}
|
||||
|
@ -249,9 +249,9 @@ int ssd1306_load_frame_buffer(const ssd1306_t *dev, uint8_t buf[])
|
|||
switch (dev->protocol) {
|
||||
#if (SSD1306_I2C_SUPPORT)
|
||||
case SSD1306_PROTO_I2C:
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
if(dev->screen == SH1106_SCREEN && i%dev->width == 0) sh1106_go_coordinate(dev,0,i/dev->width);
|
||||
for (i = 0; i < len; i++) {
|
||||
if (dev->screen == SH1106_SCREEN && i % dev->width == 0)
|
||||
sh1106_go_coordinate(dev, 0, i / dev->width);
|
||||
i2c_send(dev, 0x40, buf ? &buf[i] : tab, 16);
|
||||
i += 15;
|
||||
}
|
||||
|
@ -260,16 +260,14 @@ int ssd1306_load_frame_buffer(const ssd1306_t *dev, uint8_t buf[])
|
|||
#if (SSD1306_SPI4_SUPPORT)
|
||||
case SSD1306_PROTO_SPI4:
|
||||
gpio_write(dev->cs_pin, false);
|
||||
if(dev->screen == SSD1306_SCREEN)
|
||||
{
|
||||
if (dev->screen == SSD1306_SCREEN) {
|
||||
gpio_write(dev->dc_pin, true); // data mode
|
||||
if (buf)
|
||||
spi_transfer(SPI_BUS, buf, NULL, len, SPI_8BIT);
|
||||
else
|
||||
spi_repeat_send_8(SPI_BUS, 0, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
for (i = 0; i < (dev->height / 8); i++) {
|
||||
sh1106_go_coordinate(dev, 0, i);
|
||||
gpio_write(dev->dc_pin, true); // data mode
|
||||
|
@ -286,26 +284,20 @@ int ssd1306_load_frame_buffer(const ssd1306_t *dev, uint8_t buf[])
|
|||
#if (SSD1306_SPI3_SUPPORT)
|
||||
case SSD1306_PROTO_SPI3:
|
||||
gpio_write(dev->cs_pin, false);
|
||||
if(dev->screen == SSD1306_SCREEN)
|
||||
{
|
||||
if (dev->screen == SSD1306_SCREEN) {
|
||||
spi_set_command(SPI_BUS, 1, 1); // data mode
|
||||
if (buf)
|
||||
{
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
if (buf) {
|
||||
for (i = 0; i < len; i++) {
|
||||
spi_transfer(SPI_BUS, &buf[i], NULL, 1, SPI_8BIT);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
else {
|
||||
for (i = 0; i < len; i++) {
|
||||
spi_transfer_8(SPI_BUS, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
for (i = 0; i < (dev->height / 8); i++) {
|
||||
sh1106_go_coordinate(dev, 0, i);
|
||||
spi_set_command(SPI_BUS, 1, 1); // data mode
|
||||
|
@ -357,15 +349,13 @@ int ssd1306_set_display_offset(const ssd1306_t *dev, uint8_t offset)
|
|||
|
||||
int sh1106_set_charge_pump_voltage(const ssd1306_t *dev, sh1106_voltage_t select)
|
||||
{
|
||||
if (dev->screen == SSD1306_SCREEN)
|
||||
{
|
||||
if (dev->screen == SSD1306_SCREEN) {
|
||||
debug("Unsupported screen type");
|
||||
return -ENOTSUP;
|
||||
}
|
||||
return ssd1306_command(dev, select | SH1106_CHARGE_PUMP_VALUE);
|
||||
}
|
||||
|
||||
|
||||
int ssd1306_set_charge_pump_enabled(const ssd1306_t *dev, bool enabled)
|
||||
{
|
||||
int err = 0;
|
||||
|
@ -388,8 +378,7 @@ int ssd1306_set_charge_pump_enabled(const ssd1306_t *dev, bool enabled)
|
|||
|
||||
int ssd1306_set_mem_addr_mode(const ssd1306_t *dev, ssd1306_mem_addr_mode_t mode)
|
||||
{
|
||||
if (dev->screen == SH1106_SCREEN)
|
||||
{
|
||||
if (dev->screen == SH1106_SCREEN) {
|
||||
debug("Unsupported screen type");
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
@ -532,8 +521,7 @@ int ssd1306_draw_pixel(const ssd1306_t *dev, uint8_t *fb, int8_t x, int8_t y, ss
|
|||
return -EINVAL;
|
||||
|
||||
index = x + (y / 8) * dev->width;
|
||||
switch (color)
|
||||
{
|
||||
switch (color) {
|
||||
case OLED_COLOR_WHITE:
|
||||
fb[index] |= (1 << (y & 7));
|
||||
break;
|
||||
|
@ -565,26 +553,22 @@ int ssd1306_draw_hline(const ssd1306_t *dev, uint8_t *fb, int8_t x, int8_t y, ui
|
|||
t = w;
|
||||
index = x + (y / 8) * dev->width;
|
||||
mask = 1 << (y & 7);
|
||||
switch (color)
|
||||
{
|
||||
switch (color) {
|
||||
case OLED_COLOR_WHITE:
|
||||
while (t--)
|
||||
{
|
||||
while (t--) {
|
||||
fb[index] |= mask;
|
||||
++index;
|
||||
}
|
||||
break;
|
||||
case OLED_COLOR_BLACK:
|
||||
mask = ~mask;
|
||||
while (t--)
|
||||
{
|
||||
while (t--) {
|
||||
fb[index] &= mask;
|
||||
++index;
|
||||
}
|
||||
break;
|
||||
case OLED_COLOR_INVERT:
|
||||
while (t--)
|
||||
{
|
||||
while (t--) {
|
||||
fb[index] ^= mask;
|
||||
++index;
|
||||
}
|
||||
|
@ -619,8 +603,7 @@ int ssd1306_draw_vline(const ssd1306_t *dev, uint8_t *fb, int8_t x, int8_t y, ui
|
|||
mask = premask[mod];
|
||||
if (t < mod)
|
||||
mask &= (0xFF >> (mod - t));
|
||||
switch (color)
|
||||
{
|
||||
switch (color) {
|
||||
case OLED_COLOR_WHITE:
|
||||
fb[index] |= mask;
|
||||
break;
|
||||
|
@ -641,27 +624,23 @@ int ssd1306_draw_vline(const ssd1306_t *dev, uint8_t *fb, int8_t x, int8_t y, ui
|
|||
}
|
||||
if (t >= 8) // byte aligned line at middle
|
||||
{
|
||||
switch (color)
|
||||
{
|
||||
switch (color) {
|
||||
case OLED_COLOR_WHITE:
|
||||
do
|
||||
{
|
||||
do {
|
||||
fb[index] = 0xff;
|
||||
index += dev->width;
|
||||
t -= 8;
|
||||
} while (t >= 8);
|
||||
break;
|
||||
case OLED_COLOR_BLACK:
|
||||
do
|
||||
{
|
||||
do {
|
||||
fb[index] = 0x00;
|
||||
index += dev->width;
|
||||
t -= 8;
|
||||
} while (t >= 8);
|
||||
break;
|
||||
case OLED_COLOR_INVERT:
|
||||
do
|
||||
{
|
||||
do {
|
||||
fb[index] = ~fb[index];
|
||||
index += dev->width;
|
||||
t -= 8;
|
||||
|
@ -676,8 +655,7 @@ int ssd1306_draw_vline(const ssd1306_t *dev, uint8_t *fb, int8_t x, int8_t y, ui
|
|||
mod = t & 7;
|
||||
static const uint8_t postmask[8] = { 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F };
|
||||
mask = postmask[mod];
|
||||
switch (color)
|
||||
{
|
||||
switch (color) {
|
||||
case OLED_COLOR_WHITE:
|
||||
fb[index] |= mask;
|
||||
break;
|
||||
|
@ -706,7 +684,6 @@ int ssd1306_draw_rectangle(const ssd1306_t *dev, uint8_t *fb, int8_t x, int8_t y
|
|||
return ssd1306_draw_vline(dev, fb, x + w - 1, y, h, color);
|
||||
}
|
||||
|
||||
|
||||
int ssd1306_fill_rectangle(const ssd1306_t *dev, uint8_t *fb, int8_t x, int8_t y, uint8_t w, uint8_t h, ssd1306_color_t color)
|
||||
{
|
||||
// Can be optimized?
|
||||
|
@ -738,8 +715,7 @@ int ssd1306_draw_circle(const ssd1306_t *dev, uint8_t *fb, int8_t x0, int8_t y0,
|
|||
if ((err = ssd1306_draw_pixel(dev, fb, x0, y0 + r, color)))
|
||||
return err;
|
||||
|
||||
while (x >= y)
|
||||
{
|
||||
while (x >= y) {
|
||||
if ((err = ssd1306_draw_pixel(dev, fb, x0 + x, y0 + y, color)))
|
||||
return err;
|
||||
if ((err = ssd1306_draw_pixel(dev, fb, x0 - x, y0 + y, color)))
|
||||
|
@ -748,8 +724,7 @@ int ssd1306_draw_circle(const ssd1306_t *dev, uint8_t *fb, int8_t x0, int8_t y0,
|
|||
return err;
|
||||
if ((err = ssd1306_draw_pixel(dev, fb, x0 - x, y0 - y, color)))
|
||||
return err;
|
||||
if (x != y)
|
||||
{
|
||||
if (x != y) {
|
||||
/* Otherwise the 4 drawings below are the same as above, causing
|
||||
* problem when color is INVERT
|
||||
*/
|
||||
|
@ -788,14 +763,12 @@ int ssd1306_fill_circle(const ssd1306_t *dev, uint8_t *fb, int8_t x0, int8_t y0,
|
|||
|
||||
if ((err = ssd1306_draw_vline(dev, fb, x0, y0 - r, 2 * r + 1, color))) // Center vertical line
|
||||
return err;
|
||||
while (y >= x)
|
||||
{
|
||||
while (y >= x) {
|
||||
if ((err = ssd1306_draw_vline(dev, fb, x0 - x, y0 - y, 2 * y + 1, color)))
|
||||
return err;
|
||||
if ((err = ssd1306_draw_vline(dev, fb, x0 + x, y0 - y, 2 * y + 1, color)))
|
||||
return err;
|
||||
if (color != OLED_COLOR_INVERT)
|
||||
{
|
||||
if (color != OLED_COLOR_INVERT) {
|
||||
if ((err = ssd1306_draw_vline(dev, fb, x0 - y, y0 - x, 2 * x + 1, color)))
|
||||
return err;
|
||||
if ((err = ssd1306_draw_vline(dev, fb, x0 + y, y0 - x, 2 * x + 1, color)))
|
||||
|
@ -811,8 +784,7 @@ int ssd1306_fill_circle(const ssd1306_t *dev, uint8_t *fb, int8_t x0, int8_t y0,
|
|||
}
|
||||
}
|
||||
|
||||
if (color == OLED_COLOR_INVERT)
|
||||
{
|
||||
if (color == OLED_COLOR_INVERT) {
|
||||
x1 = x; // Save where we stopped
|
||||
|
||||
y = 1;
|
||||
|
@ -822,8 +794,7 @@ int ssd1306_fill_circle(const ssd1306_t *dev, uint8_t *fb, int8_t x0, int8_t y0,
|
|||
return err;
|
||||
if ((err = ssd1306_draw_hline(dev, fb, x0 - r, y0, r - x1 + 1, color)))
|
||||
return err;
|
||||
while (x >= y)
|
||||
{
|
||||
while (x >= y) {
|
||||
if ((err = ssd1306_draw_hline(dev, fb, x0 + x1, y0 - y, x - x1 + 1, color)))
|
||||
return err;
|
||||
if ((err = ssd1306_draw_hline(dev, fb, x0 + x1, y0 + y, x - x1 + 1, color)))
|
||||
|
@ -845,8 +816,7 @@ int ssd1306_fill_circle(const ssd1306_t *dev, uint8_t *fb, int8_t x0, int8_t y0,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int ssd1306_draw_line(const ssd1306_t *dev, uint8_t *fb, int16_t x0, int16_t y0,
|
||||
int16_t x1, int16_t y1, ssd1306_color_t color)
|
||||
int ssd1306_draw_line(const ssd1306_t *dev, uint8_t *fb, int16_t x0, int16_t y0, int16_t x1, int16_t y1, ssd1306_color_t color)
|
||||
{
|
||||
if ((x0 >= dev->width) || (x0 < 0) || (y0 >= dev->height) || (y0 < 0))
|
||||
return -EINVAL;
|
||||
|
@ -874,7 +844,8 @@ int ssd1306_draw_line(const ssd1306_t *dev, uint8_t *fb, int16_t x0, int16_t y0,
|
|||
|
||||
if (y0 < y1) {
|
||||
ystep = 1;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
ystep = -1;
|
||||
}
|
||||
|
||||
|
@ -882,7 +853,8 @@ int ssd1306_draw_line(const ssd1306_t *dev, uint8_t *fb, int16_t x0, int16_t y0,
|
|||
if (steep) {
|
||||
if ((err = ssd1306_draw_pixel(dev, fb, y0, x0, color)))
|
||||
return err;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if ((err = ssd1306_draw_pixel(dev, fb, x0, y0, color)))
|
||||
return err;
|
||||
}
|
||||
|
@ -895,8 +867,7 @@ int ssd1306_draw_line(const ssd1306_t *dev, uint8_t *fb, int16_t x0, int16_t y0,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int ssd1306_draw_triangle(const ssd1306_t *dev, uint8_t *fb, int16_t x0,
|
||||
int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2,
|
||||
int ssd1306_draw_triangle(const ssd1306_t *dev, uint8_t *fb, int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2,
|
||||
ssd1306_color_t color)
|
||||
{
|
||||
int err;
|
||||
|
@ -907,8 +878,7 @@ int ssd1306_draw_triangle(const ssd1306_t *dev, uint8_t *fb, int16_t x0,
|
|||
return ssd1306_draw_line(dev, fb, x2, y2, x0, y0, color);
|
||||
}
|
||||
|
||||
int ssd1306_fill_triangle(const ssd1306_t *dev, uint8_t *fb, int16_t x0,
|
||||
int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2,
|
||||
int ssd1306_fill_triangle(const ssd1306_t *dev, uint8_t *fb, int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2,
|
||||
ssd1306_color_t color)
|
||||
{
|
||||
int16_t a, b, y, last;
|
||||
|
@ -989,9 +959,8 @@ int ssd1306_fill_triangle(const ssd1306_t *dev, uint8_t *fb, int16_t x0,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int ssd1306_draw_char(const ssd1306_t *dev, uint8_t *fb,
|
||||
const font_info_t *font, uint8_t x, uint8_t y, char c,
|
||||
ssd1306_color_t foreground, ssd1306_color_t background)
|
||||
int ssd1306_draw_char(const ssd1306_t *dev, uint8_t *fb, const font_info_t *font, uint8_t x, uint8_t y, char c, ssd1306_color_t foreground,
|
||||
ssd1306_color_t background)
|
||||
{
|
||||
uint8_t i, j;
|
||||
const uint8_t *bitmap;
|
||||
|
@ -1015,8 +984,7 @@ int ssd1306_draw_char(const ssd1306_t *dev, uint8_t *fb,
|
|||
err = ssd1306_draw_pixel(dev, fb, x + i, y + j, foreground);
|
||||
}
|
||||
else {
|
||||
switch (background)
|
||||
{
|
||||
switch (background) {
|
||||
case OLED_COLOR_TRANSPARENT:
|
||||
// Not drawing for transparent background
|
||||
break;
|
||||
|
@ -1029,15 +997,15 @@ int ssd1306_draw_char(const ssd1306_t *dev, uint8_t *fb,
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (err) return -ERANGE ;
|
||||
if (err)
|
||||
return -ERANGE;
|
||||
line = line << 1;
|
||||
}
|
||||
}
|
||||
return d->width;
|
||||
}
|
||||
|
||||
int ssd1306_draw_string(const ssd1306_t *dev, uint8_t *fb,
|
||||
const font_info_t *font, uint8_t x, uint8_t y, char *str,
|
||||
int ssd1306_draw_string(const ssd1306_t *dev, uint8_t *fb, const font_info_t *font, uint8_t x, uint8_t y, char *str,
|
||||
ssd1306_color_t foreground, ssd1306_color_t background)
|
||||
{
|
||||
uint8_t t = x;
|
||||
|
@ -1046,8 +1014,7 @@ int ssd1306_draw_string(const ssd1306_t *dev, uint8_t *fb,
|
|||
if (font == NULL || str == NULL)
|
||||
return 0;
|
||||
|
||||
while (*str)
|
||||
{
|
||||
while (*str) {
|
||||
if ((err = ssd1306_draw_char(dev, fb, font, x, y, *str, foreground, background)) < 0)
|
||||
return err;
|
||||
x += err;
|
||||
|
@ -1067,13 +1034,11 @@ int ssd1306_start_scroll_hori(const ssd1306_t *dev, bool way, uint8_t start, uin
|
|||
{
|
||||
int err;
|
||||
|
||||
if (way)
|
||||
{
|
||||
if (way) {
|
||||
if ((err = ssd1306_command(dev, SSD1306_SCROLL_HOR_LEFT)))
|
||||
return err;
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
if ((err = ssd1306_command(dev, SSD1306_SCROLL_HOR_RIGHT)))
|
||||
return err;
|
||||
}
|
||||
|
@ -1104,13 +1069,11 @@ int ssd1306_start_scroll_hori_vert(const ssd1306_t *dev, bool way, uint8_t star
|
|||
if ((err = ssd1306_command(dev, dev->height)))
|
||||
return err;
|
||||
|
||||
if (way)
|
||||
{
|
||||
if (way) {
|
||||
if ((err = ssd1306_command(dev, SSD1306_SCROLL_HOR_VER_LEFT)))
|
||||
return err;
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
if ((err = ssd1306_command(dev, SSD1306_SCROLL_HOR_VER_RIGHT)))
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -66,11 +66,14 @@ typedef struct
|
|||
{
|
||||
ssd1306_protocol_t protocol;
|
||||
ssd1306_screen_t screen;
|
||||
union {
|
||||
union
|
||||
{
|
||||
#if (SSD1306_I2C_SUPPORT)
|
||||
i2c_dev_t i2c_dev; //!< I2C devuce descriptor, used by SSD1306_PROTO_I2C
|
||||
#endif
|
||||
#if (SSD1306_SPI4_SUPPORT) || (SSD1306_SPI3_SUPPORT)
|
||||
uint8_t cs_pin; //!< Chip Select GPIO pin, used by SSD1306_PROTO_SPI3, SSD1306_PROTO_SPI4
|
||||
#endif
|
||||
};
|
||||
#if (SSD1306_SPI4_SUPPORT)
|
||||
uint8_t dc_pin; //!< Data/Command GPIO pin, used by SSD1306_PROTO_SPI4
|
||||
|
|
|
@ -95,6 +95,13 @@
|
|||
#define B8C 0x0000 // 0.000 * 2^LUX_SCALE
|
||||
#define M8C 0x0000 // 0.000 * 2^LUX_SCALE
|
||||
|
||||
#ifdef TSL2561_DEBUG
|
||||
#include <stdio.h>
|
||||
#define debug(fmt, ...) printf("%s: " fmt "\n", "TSL2561", ## __VA_ARGS__)
|
||||
#else
|
||||
#define debug(fmt, ...)
|
||||
#endif
|
||||
|
||||
static int write_register(i2c_dev_t *i2c_dev, uint8_t reg, uint8_t value)
|
||||
{
|
||||
reg = TSL2561_REG_COMMAND | reg;
|
||||
|
@ -108,7 +115,7 @@ static uint8_t read_register(i2c_dev_t* i2c_dev, uint8_t reg)
|
|||
|
||||
if (i2c_slave_read(i2c_dev->bus, i2c_dev->addr, ®, data, 1))
|
||||
{
|
||||
printf("Error in tsl2561 read_register\n");
|
||||
debug("Error in tsl2561 read_register\n");
|
||||
}
|
||||
|
||||
return data[0];
|
||||
|
@ -122,7 +129,7 @@ static uint16_t read_register_16(i2c_dev_t* i2c_dev, uint8_t low_register_addr)
|
|||
|
||||
if (i2c_slave_read(i2c_dev->bus, i2c_dev->addr, &low_register_addr, data, 2))
|
||||
{
|
||||
printf("Error with i2c_slave_read in read_register_16\n");
|
||||
debug("Error with i2c_slave_read in read_register_16\n");
|
||||
}
|
||||
|
||||
value = ((uint16_t)data[1] << 8) | (data[0]);
|
||||
|
@ -144,14 +151,14 @@ void tsl2561_init(tsl2561_t *device)
|
|||
{
|
||||
if (enable(&device->i2c_dev))
|
||||
{
|
||||
printf("Error initializing tsl2561\n");
|
||||
debug("Error initializing tsl2561\n");
|
||||
}
|
||||
|
||||
uint8_t control_reg = (read_register(&device->i2c_dev, TSL2561_REG_CONTROL) & TSL2561_ON);
|
||||
|
||||
if (control_reg != TSL2561_ON)
|
||||
{
|
||||
printf("Error initializing tsl2561, control register wasn't set to ON\n");
|
||||
debug("Error initializing tsl2561, control register wasn't set to ON\n");
|
||||
}
|
||||
|
||||
// Fetch the package type
|
||||
|
@ -348,7 +355,7 @@ bool tsl2561_read_lux(tsl2561_t *device, uint32_t *lux)
|
|||
|
||||
break;
|
||||
default:
|
||||
printf("Invalid package type in CalculateLux\n");
|
||||
debug("Invalid package type in CalculateLux\n");
|
||||
b = 0;
|
||||
m = 0;
|
||||
success = false;
|
||||
|
|
Loading…
Reference in a new issue