Code formatted, minor fixes (#466)

This commit is contained in:
Ruslan V. Uss 2017-10-19 00:25:48 +05:00 committed by Johan Kanflo
parent 8a474d749d
commit 5fa48d0298
28 changed files with 623 additions and 608 deletions

View file

@ -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);
} }

View file

@ -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_

View file

@ -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, &reg, buf, len); return i2c_slave_read(dev->bus, dev->addr, &reg, 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, &reg, buf, len); return i2c_slave_write(dev->bus, dev->addr, &reg, buf, len);

View file

@ -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

View file

@ -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,

View file

@ -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, &reg, d, sizeof(d)) int error = i2c_slave_read(dev->bus, dev->addr, &reg, 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;
} }

View file

@ -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;
/** /**

View file

@ -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
```

View file

@ -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;
} }

View file

@ -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

View file

@ -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, &reg, data, 1)) if (i2c_slave_read(i2c_dev->bus, i2c_dev->addr, &reg, 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;