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)
|
static inline void spi_set_command(uint8_t bus, uint8_t bits, uint16_t data)
|
||||||
{
|
{
|
||||||
if (!bits) return;
|
if (!bits) return;
|
||||||
|
|
||||||
SPI(bus).USER0 |= SPI_USER0_COMMAND; //enable COMMAND function in SPI module
|
SPI(bus).USER0 |= SPI_USER0_COMMAND; //enable COMMAND function in SPI module
|
||||||
uint16_t command = data << (16 - bits); //align command data to high bits
|
uint16_t command = data << (16 - bits); //align command data to high bits
|
||||||
command = ((command >> 8) & 0xff) | ((command << 8) & 0xff00); //swap byte order
|
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)
|
static inline void spi_set_address(uint8_t bus, uint8_t bits, uint32_t data)
|
||||||
{
|
{
|
||||||
if (!bits) return;
|
if (!bits) return;
|
||||||
|
|
||||||
SPI(bus).USER0 |= SPI_USER0_ADDR; //enable ADDRess function in SPI module
|
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).ADDR = data << (32 - bits); //align address data to high bits
|
||||||
SPI(bus).USER1 = SET_FIELD(SPI(bus).USER1, SPI_USER1_ADDR_BITLEN, --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)
|
static inline void spi_set_dummy_bits(uint8_t bus, uint8_t bits, bool pos)
|
||||||
{
|
{
|
||||||
if (!bits) return;
|
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).USER0 |= SPI_USER0_DUMMY; //enable dummy bits
|
||||||
SPI(bus).USER1 = SET_FIELD(SPI(bus).USER1, SPI_USER1_DUMMY_CYCLELEN, --bits);
|
SPI(bus).USER1 = SET_FIELD(SPI(bus).USER1, SPI_USER1_DUMMY_CYCLELEN, --bits);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
*
|
*
|
||||||
* Part of esp-open-rtos
|
* Part of esp-open-rtos
|
||||||
* Copyright (C) 2016 Ruslan V. Uss <unclerus@gmail.com>,
|
* 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
|
* BSD Licensed as described in the file LICENSE
|
||||||
*/
|
*/
|
||||||
#ifndef EXTRAS_DS1302_H_
|
#ifndef EXTRAS_DS1302_H_
|
||||||
|
|
|
@ -78,7 +78,8 @@ void ds1307_get_time(i2c_dev_t* dev, struct tm *time)
|
||||||
if (buf[2] & PM_BIT)
|
if (buf[2] & PM_BIT)
|
||||||
time->tm_hour += 12;
|
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_wday = bcd2dec(buf[3]) - 1;
|
||||||
time->tm_mday = bcd2dec(buf[4]);
|
time->tm_mday = bcd2dec(buf[4]);
|
||||||
time->tm_mon = bcd2dec(buf[5]) - 1;
|
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)
|
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;
|
uint8_t reg = RAM_REG + offset;
|
||||||
|
|
||||||
return i2c_slave_read(dev->bus, dev->addr, ®, buf, len);
|
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)
|
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;
|
uint8_t reg = RAM_REG + offset;
|
||||||
|
|
||||||
return i2c_slave_write(dev->bus, dev->addr, ®, buf, len);
|
return i2c_slave_write(dev->bus, dev->addr, ®, buf, len);
|
||||||
|
|
|
@ -18,10 +18,11 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define DS1307_ADDR 0x68
|
#define DS1307_ADDR 0x68
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Squarewave frequency
|
* Squarewave frequency
|
||||||
*/
|
*/
|
||||||
typedef enum _ds1307_squarewave_freq_t
|
typedef enum
|
||||||
{
|
{
|
||||||
DS1307_1HZ = 0, //!< 1 Hz
|
DS1307_1HZ = 0, //!< 1 Hz
|
||||||
DS1307_4096HZ, //!< 4096 Hz
|
DS1307_4096HZ, //!< 4096 Hz
|
||||||
|
|
|
@ -104,7 +104,7 @@ hd44780_t lcd = {
|
||||||
hd44780_t lcd = {
|
hd44780_t lcd = {
|
||||||
.addr = ADDR,
|
.addr = ADDR,
|
||||||
.font = HD44780_FONT_5X8,
|
.font = HD44780_FONT_5X8,
|
||||||
.lines = 2,
|
.lines = 4,
|
||||||
.pins = {
|
.pins = {
|
||||||
.rs = 0,
|
.rs = 0,
|
||||||
.e = 2,
|
.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)
|
static int _wireReadRegister(const i2c_dev_t *dev, uint8_t reg, uint16_t *value)
|
||||||
{
|
{
|
||||||
uint8_t d[] = { 0, 0 };
|
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);
|
debug("Data read from bus %u at %02X: %02X+%04X\n", dev->bus, dev->addr, reg, *value);
|
||||||
*value = d[1] | (d[0] << 8);
|
*value = d[1] | (d[0] << 8);
|
||||||
return error;
|
return error;
|
||||||
|
@ -53,14 +53,16 @@ int ina3221_sync(ina3221_t *dev)
|
||||||
//////////////////////// Sync config register
|
//////////////////////// Sync config register
|
||||||
if ((err = _wireReadRegister(&dev->i2c_dev, INA3221_REG_CONFIG, &ptr_data))) // Read config
|
if ((err = _wireReadRegister(&dev->i2c_dev, INA3221_REG_CONFIG, &ptr_data))) // Read config
|
||||||
return err;
|
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
|
if ((err = _wireWriteRegister(&dev->i2c_dev, INA3221_REG_CONFIG, dev->config.config_register))) // Update config
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
//////////////////////// Sync mask register config
|
//////////////////////// Sync mask register config
|
||||||
if ((err = _wireReadRegister(&dev->i2c_dev, INA3221_REG_MASK, &ptr_data))) // Read mask
|
if ((err = _wireReadRegister(&dev->i2c_dev, INA3221_REG_MASK, &ptr_data))) // Read mask
|
||||||
return err;
|
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
|
if ((err = _wireWriteRegister(&dev->i2c_dev, INA3221_REG_MASK, dev->mask.mask_register & INA3221_MASK_CONFIG))) // Update config
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,14 +19,14 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "i2c/i2c.h"
|
#include <i2c/i2c.h>
|
||||||
|
|
||||||
#define INA3221_ADDR_0 (0x40) // A0 to GND
|
#define INA3221_ADDR_0 (0x40) ///< A0 to GND
|
||||||
#define INA3221_ADDR_1 (0x41) // A0 to Vs+
|
#define INA3221_ADDR_1 (0x41) ///< A0 to Vs+
|
||||||
#define INA3221_ADDR_2 (0x42) // A0 to SDA
|
#define INA3221_ADDR_2 (0x42) ///< A0 to SDA
|
||||||
#define INA3221_ADDR_3 (0x43) // A0 to SCL
|
#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_CONFIG (0x00)
|
||||||
#define INA3221_REG_SHUNTVOLTAGE_1 (0x01)
|
#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_UPPER_LIMIT (0x10)
|
||||||
#define INA3221_REG_VALID_POWER_LOWER_LIMIT (0x11)
|
#define INA3221_REG_VALID_POWER_LOWER_LIMIT (0x11)
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Default register after reset
|
* Default register after reset
|
||||||
*/
|
*/
|
||||||
#define INA3221_DEFAULT_CONFIG (0x7127)
|
#define INA3221_DEFAULT_CONFIG (0x7127)
|
||||||
|
@ -48,11 +48,12 @@ extern "C" {
|
||||||
#define INA3221_DEFAULT_POWER_LOWER_LIMIT (0x2328) //9V
|
#define INA3221_DEFAULT_POWER_LOWER_LIMIT (0x2328) //9V
|
||||||
|
|
||||||
#define INA3221_MASK_CONFIG (0x7C00)
|
#define INA3221_MASK_CONFIG (0x7C00)
|
||||||
/*
|
|
||||||
* Numbrer of samples
|
/**
|
||||||
|
* Number of samples
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
INA3221_AVG_1 = 0, //Default
|
INA3221_AVG_1 = 0, ///< Default
|
||||||
INA3221_AVG_4,
|
INA3221_AVG_4,
|
||||||
INA3221_AVG_16,
|
INA3221_AVG_16,
|
||||||
INA3221_AVG_64,
|
INA3221_AVG_64,
|
||||||
|
@ -62,7 +63,7 @@ typedef enum {
|
||||||
INA3221_AVG_1024,
|
INA3221_AVG_1024,
|
||||||
} ina3221_avg_t;
|
} ina3221_avg_t;
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Channel selection list
|
* Channel selection list
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -71,7 +72,7 @@ typedef enum {
|
||||||
CHANNEL_3,
|
CHANNEL_3,
|
||||||
} ina3221_channel_t;
|
} ina3221_channel_t;
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Conversion time in us
|
* Conversion time in us
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -79,63 +80,63 @@ typedef enum {
|
||||||
INA3221_CT_204,
|
INA3221_CT_204,
|
||||||
INA3221_CT_332,
|
INA3221_CT_332,
|
||||||
INA3221_CT_588,
|
INA3221_CT_588,
|
||||||
INA3221_CT_1100, //Default
|
INA3221_CT_1100, ///< Default
|
||||||
INA3221_CT_2116,
|
INA3221_CT_2116,
|
||||||
INA3221_CT_4156,
|
INA3221_CT_4156,
|
||||||
INA3221_CT_8244,
|
INA3221_CT_8244,
|
||||||
} ina3221_ct_t;
|
} ina3221_ct_t;
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Config description register
|
* Config description register
|
||||||
*/
|
*/
|
||||||
typedef union
|
typedef union
|
||||||
{
|
{
|
||||||
struct {
|
struct {
|
||||||
uint16_t esht : 1; // Enable/Disable shunt measure // LSB
|
uint16_t esht : 1; ///< Enable/Disable shunt measure // LSB
|
||||||
uint16_t ebus : 1; // Enable/Disable bus measure
|
uint16_t ebus : 1; ///< Enable/Disable bus measure
|
||||||
uint16_t mode : 1; // Single shot measure or continious mode
|
uint16_t mode : 1; ///< Single shot measure or continious mode
|
||||||
uint16_t vsht : 3; // Shunt voltage conversion time
|
uint16_t vsht : 3; ///< Shunt voltage conversion time
|
||||||
uint16_t vbus : 3; // Bus voltage conversion time
|
uint16_t vbus : 3; ///< Bus voltage conversion time
|
||||||
uint16_t avg : 3; // number of sample collected and averaged together
|
uint16_t avg : 3; ///< number of sample collected and averaged together
|
||||||
uint16_t ch3 : 1; // Enable/Disable channel 3
|
uint16_t ch3 : 1; ///< Enable/Disable channel 3
|
||||||
uint16_t ch2 : 1; // Enable/Disable channel 2
|
uint16_t ch2 : 1; ///< Enable/Disable channel 2
|
||||||
uint16_t ch1 : 1; // Enable/Disable channel 1
|
uint16_t ch1 : 1; ///< Enable/Disable channel 1
|
||||||
uint16_t rst : 1; //Set this bit to 1 to reset device // MSB
|
uint16_t rst : 1; ///< Set this bit to 1 to reset device // MSB
|
||||||
};
|
};
|
||||||
uint16_t config_register;
|
uint16_t config_register;
|
||||||
} ina3221_config_t;
|
} ina3221_config_t;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Mask/enable description register
|
* Mask/enable description register
|
||||||
*/
|
*/
|
||||||
typedef union
|
typedef union
|
||||||
{
|
{
|
||||||
struct {
|
struct {
|
||||||
uint16_t cvrf : 1 ; // Conversion ready flag (1: ready) // LSB
|
uint16_t cvrf : 1; ///< Conversion ready flag (1: ready) // LSB
|
||||||
uint16_t tcf : 1 ; // Timing control flag
|
uint16_t tcf : 1; ///< Timing control flag
|
||||||
uint16_t pvf : 1 ; // Power valid 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 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 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 cf : 3; ///< Critical alert flag (Read mask to clear) (order : Channel1:channel2:channel3)
|
||||||
uint16_t cen : 1 ; // Critical alert latch (1:enable)
|
uint16_t cen : 1; ///< Critical alert latch (1:enable)
|
||||||
uint16_t wen : 1 ; // Warning alert latch (1:enable)
|
uint16_t wen : 1; ///< Warning alert latch (1:enable)
|
||||||
uint16_t scc3 : 1 ; // channel 3 sum (1:enable)
|
uint16_t scc3 : 1; ///< channel 3 sum (1:enable)
|
||||||
uint16_t scc2 : 1 ; // channel 2 sum (1:enable)
|
uint16_t scc2 : 1; ///< channel 2 sum (1:enable)
|
||||||
uint16_t scc1 : 1 ; // channel 1 sum (1:enable)
|
uint16_t scc1 : 1; ///< channel 1 sum (1:enable)
|
||||||
uint16_t : 1 ; //Reserved //MSB
|
uint16_t : 1; ///< Reserved //MSB
|
||||||
};
|
};
|
||||||
uint16_t mask_register;
|
uint16_t mask_register;
|
||||||
} ina3221_mask_t;
|
} ina3221_mask_t;
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Device description
|
* Device description
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const i2c_dev_t i2c_dev; // ina3221 I2C address
|
const i2c_dev_t i2c_dev; ///< ina3221 I2C address
|
||||||
const uint16_t shunt[BUS_NUMBER]; //Memory of shunt value (mOhm)
|
const uint16_t shunt[BUS_NUMBER]; ///< Memory of shunt value (mOhm)
|
||||||
ina3221_config_t config; //Memory of ina3221 config
|
ina3221_config_t config; ///< Memory of ina3221 config
|
||||||
ina3221_mask_t mask; //Memory of mask_config
|
ina3221_mask_t mask; ///< Memory of mask_config
|
||||||
} ina3221_t;
|
} 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)).
|
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
|
## Supported connection interfaces
|
||||||
|
|
||||||
Currently supported two of them: I2C and SPI4.
|
I2C, SPI3 and SPI4.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
If Reset pin is accesible in your display module, connect it to the RESET pin of ESP8266.
|
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
|
### I2C protocol
|
||||||
|
|
||||||
Before using the SSD1306 LCD module the function `i2c_init(SCL_PIN, SDA_PIN)` needs to be
|
Before using the OLED module you need to call the function `i2c_init(BUS, SCL_PIN, SDA_PIN, I2C_FREQ_400K)`
|
||||||
called to setup the I2C interface and then you must call `ssd1306_init()`.
|
to configure the I2C interface and then you should call `ssd1306_init()`.
|
||||||
|
|
||||||
#### Example
|
#### Example
|
||||||
|
|
||||||
```C
|
```C
|
||||||
#define SCL_PIN 5
|
#define SCL_PIN 5
|
||||||
#define SDA_PIN 4
|
#define SDA_PIN 4
|
||||||
|
#define I2C_BUS 0
|
||||||
...
|
...
|
||||||
|
|
||||||
static const ssd1306_t device = {
|
static const ssd1306_t device = {
|
||||||
.protocol = SSD1306_PROTO_I2C,
|
.protocol = SSD1306_PROTO_I2C,
|
||||||
|
.screen = SSD1306_SCREEN, // or SH1106_SCREEN
|
||||||
|
.i2c_dev.bus = I2C_BUS,
|
||||||
|
.i2c_dev.addr = SSD1306_I2C_ADDR_0,
|
||||||
.width = 128,
|
.width = 128,
|
||||||
.height = 64
|
.height = 64
|
||||||
};
|
};
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
i2c_init(SCL_PIN, SDA_PIN);
|
i2c_init(I2C_BUS, SCL_PIN, SDA_PIN, I2C_FREQ_400K);
|
||||||
|
|
||||||
if (ssd1306_init(&device)) {
|
if (ssd1306_init(&device)) {
|
||||||
// An error occured, while performing SSD1306 init (E.g device not found etc.)
|
// 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
|
// 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
|
These protocols are MUCH faster than I2C, but use 2 additional GPIO pins
|
||||||
and HSPI MOSI): Data/Command pin and Chip Select pin.
|
(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()`.
|
No additional function calls are required before `ssd1306_init()`.
|
||||||
|
|
||||||
#### Example
|
|
||||||
|
#### SPI4 Example
|
||||||
|
|
||||||
```C
|
```C
|
||||||
#define CS_PIN 5
|
#define CS_PIN 5
|
||||||
|
@ -64,6 +69,7 @@ No additional function calls are required before `ssd1306_init()`.
|
||||||
|
|
||||||
static const ssd1306_t device = {
|
static const ssd1306_t device = {
|
||||||
.protocol = SSD1306_PROTO_SPI4,
|
.protocol = SSD1306_PROTO_SPI4,
|
||||||
|
.screen = SSD1306_SCREEN,
|
||||||
.cs_pin = CS_PIN,
|
.cs_pin = CS_PIN,
|
||||||
.dc_pin = DC_PIN,
|
.dc_pin = DC_PIN,
|
||||||
.width = 128,
|
.width = 128,
|
||||||
|
@ -78,3 +84,27 @@ if (ssd1306_init(&device)) {
|
||||||
|
|
||||||
// rest of the code
|
// 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 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)
|
#define swap(x, y) do { typeof(x) temp##x##y = x; x = y; y = temp##x##y; } while (0)
|
||||||
|
|
||||||
|
|
||||||
#if (SSD1306_I2C_SUPPORT)
|
#if (SSD1306_I2C_SUPPORT)
|
||||||
static int inline i2c_send(const ssd1306_t *dev, uint8_t reg, uint8_t* data, uint8_t len)
|
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;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sh1106_go_coordinate(const ssd1306_t *dev, uint8_t x, uint8_t y) {
|
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;
|
{
|
||||||
|
if (x >= dev->width || y >= (dev->height / 8))
|
||||||
|
return -EINVAL;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
x += 2; //offset : panel is 128 ; RAM is 132 for sh1106
|
x += 2; //offset : panel is 128 ; RAM is 132 for sh1106
|
||||||
if ((err = ssd1306_command(dev, SH1106_SET_PAGE_ADDRESS + y))) // Set row
|
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 };
|
uint8_t tab[16] = { 0 };
|
||||||
#endif
|
#endif
|
||||||
size_t len = dev->width * dev->height / 8;
|
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_column_addr(dev, 0, dev->width - 1);
|
||||||
ssd1306_set_page_addr(dev, 0, dev->height / 8 - 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) {
|
switch (dev->protocol) {
|
||||||
#if (SSD1306_I2C_SUPPORT)
|
#if (SSD1306_I2C_SUPPORT)
|
||||||
case SSD1306_PROTO_I2C:
|
case SSD1306_PROTO_I2C:
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++) {
|
||||||
{
|
if (dev->screen == SH1106_SCREEN && i % dev->width == 0)
|
||||||
if(dev->screen == SH1106_SCREEN && i%dev->width == 0) sh1106_go_coordinate(dev,0,i/dev->width);
|
sh1106_go_coordinate(dev, 0, i / dev->width);
|
||||||
i2c_send(dev, 0x40, buf ? &buf[i] : tab, 16);
|
i2c_send(dev, 0x40, buf ? &buf[i] : tab, 16);
|
||||||
i += 15;
|
i += 15;
|
||||||
}
|
}
|
||||||
|
@ -260,16 +260,14 @@ int ssd1306_load_frame_buffer(const ssd1306_t *dev, uint8_t buf[])
|
||||||
#if (SSD1306_SPI4_SUPPORT)
|
#if (SSD1306_SPI4_SUPPORT)
|
||||||
case SSD1306_PROTO_SPI4:
|
case SSD1306_PROTO_SPI4:
|
||||||
gpio_write(dev->cs_pin, false);
|
gpio_write(dev->cs_pin, false);
|
||||||
if(dev->screen == SSD1306_SCREEN)
|
if (dev->screen == SSD1306_SCREEN) {
|
||||||
{
|
|
||||||
gpio_write(dev->dc_pin, true); // data mode
|
gpio_write(dev->dc_pin, true); // data mode
|
||||||
if (buf)
|
if (buf)
|
||||||
spi_transfer(SPI_BUS, buf, NULL, len, SPI_8BIT);
|
spi_transfer(SPI_BUS, buf, NULL, len, SPI_8BIT);
|
||||||
else
|
else
|
||||||
spi_repeat_send_8(SPI_BUS, 0, len);
|
spi_repeat_send_8(SPI_BUS, 0, len);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
for (i = 0; i < (dev->height / 8); i++) {
|
for (i = 0; i < (dev->height / 8); i++) {
|
||||||
sh1106_go_coordinate(dev, 0, i);
|
sh1106_go_coordinate(dev, 0, i);
|
||||||
gpio_write(dev->dc_pin, true); // data mode
|
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)
|
#if (SSD1306_SPI3_SUPPORT)
|
||||||
case SSD1306_PROTO_SPI3:
|
case SSD1306_PROTO_SPI3:
|
||||||
gpio_write(dev->cs_pin, false);
|
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
|
spi_set_command(SPI_BUS, 1, 1); // data mode
|
||||||
if (buf)
|
if (buf) {
|
||||||
{
|
for (i = 0; i < len; i++) {
|
||||||
for (i = 0; i < len; i++)
|
|
||||||
{
|
|
||||||
spi_transfer(SPI_BUS, &buf[i], NULL, 1, SPI_8BIT);
|
spi_transfer(SPI_BUS, &buf[i], NULL, 1, SPI_8BIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
for (i = 0; i < len; i++) {
|
||||||
for (i = 0; i < len; i++)
|
|
||||||
{
|
|
||||||
spi_transfer_8(SPI_BUS, 0);
|
spi_transfer_8(SPI_BUS, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
for (i = 0; i < (dev->height / 8); i++) {
|
for (i = 0; i < (dev->height / 8); i++) {
|
||||||
sh1106_go_coordinate(dev, 0, i);
|
sh1106_go_coordinate(dev, 0, i);
|
||||||
spi_set_command(SPI_BUS, 1, 1); // data mode
|
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)
|
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");
|
debug("Unsupported screen type");
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
return ssd1306_command(dev, select | SH1106_CHARGE_PUMP_VALUE);
|
return ssd1306_command(dev, select | SH1106_CHARGE_PUMP_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int ssd1306_set_charge_pump_enabled(const ssd1306_t *dev, bool enabled)
|
int ssd1306_set_charge_pump_enabled(const ssd1306_t *dev, bool enabled)
|
||||||
{
|
{
|
||||||
int err = 0;
|
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)
|
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");
|
debug("Unsupported screen type");
|
||||||
return -ENOTSUP;
|
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;
|
return -EINVAL;
|
||||||
|
|
||||||
index = x + (y / 8) * dev->width;
|
index = x + (y / 8) * dev->width;
|
||||||
switch (color)
|
switch (color) {
|
||||||
{
|
|
||||||
case OLED_COLOR_WHITE:
|
case OLED_COLOR_WHITE:
|
||||||
fb[index] |= (1 << (y & 7));
|
fb[index] |= (1 << (y & 7));
|
||||||
break;
|
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;
|
t = w;
|
||||||
index = x + (y / 8) * dev->width;
|
index = x + (y / 8) * dev->width;
|
||||||
mask = 1 << (y & 7);
|
mask = 1 << (y & 7);
|
||||||
switch (color)
|
switch (color) {
|
||||||
{
|
|
||||||
case OLED_COLOR_WHITE:
|
case OLED_COLOR_WHITE:
|
||||||
while (t--)
|
while (t--) {
|
||||||
{
|
|
||||||
fb[index] |= mask;
|
fb[index] |= mask;
|
||||||
++index;
|
++index;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OLED_COLOR_BLACK:
|
case OLED_COLOR_BLACK:
|
||||||
mask = ~mask;
|
mask = ~mask;
|
||||||
while (t--)
|
while (t--) {
|
||||||
{
|
|
||||||
fb[index] &= mask;
|
fb[index] &= mask;
|
||||||
++index;
|
++index;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OLED_COLOR_INVERT:
|
case OLED_COLOR_INVERT:
|
||||||
while (t--)
|
while (t--) {
|
||||||
{
|
|
||||||
fb[index] ^= mask;
|
fb[index] ^= mask;
|
||||||
++index;
|
++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];
|
mask = premask[mod];
|
||||||
if (t < mod)
|
if (t < mod)
|
||||||
mask &= (0xFF >> (mod - t));
|
mask &= (0xFF >> (mod - t));
|
||||||
switch (color)
|
switch (color) {
|
||||||
{
|
|
||||||
case OLED_COLOR_WHITE:
|
case OLED_COLOR_WHITE:
|
||||||
fb[index] |= mask;
|
fb[index] |= mask;
|
||||||
break;
|
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
|
if (t >= 8) // byte aligned line at middle
|
||||||
{
|
{
|
||||||
switch (color)
|
switch (color) {
|
||||||
{
|
|
||||||
case OLED_COLOR_WHITE:
|
case OLED_COLOR_WHITE:
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
fb[index] = 0xff;
|
fb[index] = 0xff;
|
||||||
index += dev->width;
|
index += dev->width;
|
||||||
t -= 8;
|
t -= 8;
|
||||||
} while (t >= 8);
|
} while (t >= 8);
|
||||||
break;
|
break;
|
||||||
case OLED_COLOR_BLACK:
|
case OLED_COLOR_BLACK:
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
fb[index] = 0x00;
|
fb[index] = 0x00;
|
||||||
index += dev->width;
|
index += dev->width;
|
||||||
t -= 8;
|
t -= 8;
|
||||||
} while (t >= 8);
|
} while (t >= 8);
|
||||||
break;
|
break;
|
||||||
case OLED_COLOR_INVERT:
|
case OLED_COLOR_INVERT:
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
fb[index] = ~fb[index];
|
fb[index] = ~fb[index];
|
||||||
index += dev->width;
|
index += dev->width;
|
||||||
t -= 8;
|
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;
|
mod = t & 7;
|
||||||
static const uint8_t postmask[8] = { 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F };
|
static const uint8_t postmask[8] = { 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F };
|
||||||
mask = postmask[mod];
|
mask = postmask[mod];
|
||||||
switch (color)
|
switch (color) {
|
||||||
{
|
|
||||||
case OLED_COLOR_WHITE:
|
case OLED_COLOR_WHITE:
|
||||||
fb[index] |= mask;
|
fb[index] |= mask;
|
||||||
break;
|
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);
|
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)
|
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?
|
// 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)))
|
if ((err = ssd1306_draw_pixel(dev, fb, x0, y0 + r, color)))
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
while (x >= y)
|
while (x >= y) {
|
||||||
{
|
|
||||||
if ((err = ssd1306_draw_pixel(dev, fb, x0 + x, y0 + y, color)))
|
if ((err = ssd1306_draw_pixel(dev, fb, x0 + x, y0 + y, color)))
|
||||||
return err;
|
return err;
|
||||||
if ((err = ssd1306_draw_pixel(dev, fb, x0 - x, y0 + y, color)))
|
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;
|
return err;
|
||||||
if ((err = ssd1306_draw_pixel(dev, fb, x0 - x, y0 - y, color)))
|
if ((err = ssd1306_draw_pixel(dev, fb, x0 - x, y0 - y, color)))
|
||||||
return err;
|
return err;
|
||||||
if (x != y)
|
if (x != y) {
|
||||||
{
|
|
||||||
/* Otherwise the 4 drawings below are the same as above, causing
|
/* Otherwise the 4 drawings below are the same as above, causing
|
||||||
* problem when color is INVERT
|
* 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
|
if ((err = ssd1306_draw_vline(dev, fb, x0, y0 - r, 2 * r + 1, color))) // Center vertical line
|
||||||
return err;
|
return err;
|
||||||
while (y >= x)
|
while (y >= x) {
|
||||||
{
|
|
||||||
if ((err = ssd1306_draw_vline(dev, fb, x0 - x, y0 - y, 2 * y + 1, color)))
|
if ((err = ssd1306_draw_vline(dev, fb, x0 - x, y0 - y, 2 * y + 1, color)))
|
||||||
return err;
|
return err;
|
||||||
if ((err = ssd1306_draw_vline(dev, fb, x0 + x, y0 - y, 2 * y + 1, color)))
|
if ((err = ssd1306_draw_vline(dev, fb, x0 + x, y0 - y, 2 * y + 1, color)))
|
||||||
return err;
|
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)))
|
if ((err = ssd1306_draw_vline(dev, fb, x0 - y, y0 - x, 2 * x + 1, color)))
|
||||||
return err;
|
return err;
|
||||||
if ((err = ssd1306_draw_vline(dev, fb, x0 + y, y0 - x, 2 * x + 1, color)))
|
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
|
x1 = x; // Save where we stopped
|
||||||
|
|
||||||
y = 1;
|
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;
|
return err;
|
||||||
if ((err = ssd1306_draw_hline(dev, fb, x0 - r, y0, r - x1 + 1, color)))
|
if ((err = ssd1306_draw_hline(dev, fb, x0 - r, y0, r - x1 + 1, color)))
|
||||||
return err;
|
return err;
|
||||||
while (x >= y)
|
while (x >= y) {
|
||||||
{
|
|
||||||
if ((err = ssd1306_draw_hline(dev, fb, x0 + x1, y0 - y, x - x1 + 1, color)))
|
if ((err = ssd1306_draw_hline(dev, fb, x0 + x1, y0 - y, x - x1 + 1, color)))
|
||||||
return err;
|
return err;
|
||||||
if ((err = ssd1306_draw_hline(dev, fb, x0 + x1, y0 + y, x - x1 + 1, color)))
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ssd1306_draw_line(const ssd1306_t *dev, uint8_t *fb, int16_t x0, int16_t y0,
|
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)
|
||||||
int16_t x1, int16_t y1, ssd1306_color_t color)
|
|
||||||
{
|
{
|
||||||
if ((x0 >= dev->width) || (x0 < 0) || (y0 >= dev->height) || (y0 < 0))
|
if ((x0 >= dev->width) || (x0 < 0) || (y0 >= dev->height) || (y0 < 0))
|
||||||
return -EINVAL;
|
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) {
|
if (y0 < y1) {
|
||||||
ystep = 1;
|
ystep = 1;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
ystep = -1;
|
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 (steep) {
|
||||||
if ((err = ssd1306_draw_pixel(dev, fb, y0, x0, color)))
|
if ((err = ssd1306_draw_pixel(dev, fb, y0, x0, color)))
|
||||||
return err;
|
return err;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
if ((err = ssd1306_draw_pixel(dev, fb, x0, y0, color)))
|
if ((err = ssd1306_draw_pixel(dev, fb, x0, y0, color)))
|
||||||
return err;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ssd1306_draw_triangle(const ssd1306_t *dev, uint8_t *fb, int16_t x0,
|
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,
|
||||||
int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2,
|
|
||||||
ssd1306_color_t color)
|
ssd1306_color_t color)
|
||||||
{
|
{
|
||||||
int err;
|
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);
|
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,
|
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,
|
||||||
int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2,
|
|
||||||
ssd1306_color_t color)
|
ssd1306_color_t color)
|
||||||
{
|
{
|
||||||
int16_t a, b, y, last;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ssd1306_draw_char(const ssd1306_t *dev, uint8_t *fb,
|
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,
|
||||||
const font_info_t *font, uint8_t x, uint8_t y, char c,
|
ssd1306_color_t background)
|
||||||
ssd1306_color_t foreground, ssd1306_color_t background)
|
|
||||||
{
|
{
|
||||||
uint8_t i, j;
|
uint8_t i, j;
|
||||||
const uint8_t *bitmap;
|
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);
|
err = ssd1306_draw_pixel(dev, fb, x + i, y + j, foreground);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
switch (background)
|
switch (background) {
|
||||||
{
|
|
||||||
case OLED_COLOR_TRANSPARENT:
|
case OLED_COLOR_TRANSPARENT:
|
||||||
// Not drawing for transparent background
|
// Not drawing for transparent background
|
||||||
break;
|
break;
|
||||||
|
@ -1029,15 +997,15 @@ int ssd1306_draw_char(const ssd1306_t *dev, uint8_t *fb,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (err) return -ERANGE ;
|
if (err)
|
||||||
|
return -ERANGE;
|
||||||
line = line << 1;
|
line = line << 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return d->width;
|
return d->width;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ssd1306_draw_string(const ssd1306_t *dev, uint8_t *fb,
|
int ssd1306_draw_string(const ssd1306_t *dev, uint8_t *fb, const font_info_t *font, uint8_t x, uint8_t y, char *str,
|
||||||
const font_info_t *font, uint8_t x, uint8_t y, char *str,
|
|
||||||
ssd1306_color_t foreground, ssd1306_color_t background)
|
ssd1306_color_t foreground, ssd1306_color_t background)
|
||||||
{
|
{
|
||||||
uint8_t t = x;
|
uint8_t t = x;
|
||||||
|
@ -1046,8 +1014,7 @@ int ssd1306_draw_string(const ssd1306_t *dev, uint8_t *fb,
|
||||||
if (font == NULL || str == NULL)
|
if (font == NULL || str == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
while (*str)
|
while (*str) {
|
||||||
{
|
|
||||||
if ((err = ssd1306_draw_char(dev, fb, font, x, y, *str, foreground, background)) < 0)
|
if ((err = ssd1306_draw_char(dev, fb, font, x, y, *str, foreground, background)) < 0)
|
||||||
return err;
|
return err;
|
||||||
x += err;
|
x += err;
|
||||||
|
@ -1067,13 +1034,11 @@ int ssd1306_start_scroll_hori(const ssd1306_t *dev, bool way, uint8_t start, uin
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (way)
|
if (way) {
|
||||||
{
|
|
||||||
if ((err = ssd1306_command(dev, SSD1306_SCROLL_HOR_LEFT)))
|
if ((err = ssd1306_command(dev, SSD1306_SCROLL_HOR_LEFT)))
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
if ((err = ssd1306_command(dev, SSD1306_SCROLL_HOR_RIGHT)))
|
if ((err = ssd1306_command(dev, SSD1306_SCROLL_HOR_RIGHT)))
|
||||||
return err;
|
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)))
|
if ((err = ssd1306_command(dev, dev->height)))
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
if (way)
|
if (way) {
|
||||||
{
|
|
||||||
if ((err = ssd1306_command(dev, SSD1306_SCROLL_HOR_VER_LEFT)))
|
if ((err = ssd1306_command(dev, SSD1306_SCROLL_HOR_VER_LEFT)))
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
if ((err = ssd1306_command(dev, SSD1306_SCROLL_HOR_VER_RIGHT)))
|
if ((err = ssd1306_command(dev, SSD1306_SCROLL_HOR_VER_RIGHT)))
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,11 +66,14 @@ typedef struct
|
||||||
{
|
{
|
||||||
ssd1306_protocol_t protocol;
|
ssd1306_protocol_t protocol;
|
||||||
ssd1306_screen_t screen;
|
ssd1306_screen_t screen;
|
||||||
union {
|
union
|
||||||
|
{
|
||||||
#if (SSD1306_I2C_SUPPORT)
|
#if (SSD1306_I2C_SUPPORT)
|
||||||
i2c_dev_t i2c_dev; //!< I2C devuce descriptor, used by SSD1306_PROTO_I2C
|
i2c_dev_t i2c_dev; //!< I2C devuce descriptor, used by SSD1306_PROTO_I2C
|
||||||
#endif
|
#endif
|
||||||
|
#if (SSD1306_SPI4_SUPPORT) || (SSD1306_SPI3_SUPPORT)
|
||||||
uint8_t cs_pin; //!< Chip Select GPIO pin, used by SSD1306_PROTO_SPI3, SSD1306_PROTO_SPI4
|
uint8_t cs_pin; //!< Chip Select GPIO pin, used by SSD1306_PROTO_SPI3, SSD1306_PROTO_SPI4
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
#if (SSD1306_SPI4_SUPPORT)
|
#if (SSD1306_SPI4_SUPPORT)
|
||||||
uint8_t dc_pin; //!< Data/Command GPIO pin, used by SSD1306_PROTO_SPI4
|
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 B8C 0x0000 // 0.000 * 2^LUX_SCALE
|
||||||
#define M8C 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)
|
static int write_register(i2c_dev_t *i2c_dev, uint8_t reg, uint8_t value)
|
||||||
{
|
{
|
||||||
reg = TSL2561_REG_COMMAND | reg;
|
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))
|
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];
|
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))
|
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]);
|
value = ((uint16_t)data[1] << 8) | (data[0]);
|
||||||
|
@ -144,14 +151,14 @@ void tsl2561_init(tsl2561_t *device)
|
||||||
{
|
{
|
||||||
if (enable(&device->i2c_dev))
|
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);
|
uint8_t control_reg = (read_register(&device->i2c_dev, TSL2561_REG_CONTROL) & TSL2561_ON);
|
||||||
|
|
||||||
if (control_reg != 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
|
// Fetch the package type
|
||||||
|
@ -348,7 +355,7 @@ bool tsl2561_read_lux(tsl2561_t *device, uint32_t *lux)
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("Invalid package type in CalculateLux\n");
|
debug("Invalid package type in CalculateLux\n");
|
||||||
b = 0;
|
b = 0;
|
||||||
m = 0;
|
m = 0;
|
||||||
success = false;
|
success = false;
|
||||||
|
|
Loading…
Reference in a new issue