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

@ -186,7 +186,7 @@ void spi_set_frequency_div(uint8_t bus, uint32_t divider);
inline uint32_t spi_get_frequency_div(uint8_t bus) inline uint32_t spi_get_frequency_div(uint8_t bus)
{ {
return (FIELD2VAL(SPI_CLOCK_DIV_PRE, SPI(bus).CLOCK) + 1) | return (FIELD2VAL(SPI_CLOCK_DIV_PRE, SPI(bus).CLOCK) + 1) |
(FIELD2VAL(SPI_CLOCK_COUNT_NUM, SPI(bus).CLOCK) + 1); (FIELD2VAL(SPI_CLOCK_COUNT_NUM, SPI(bus).CLOCK) + 1);
} }
/** /**
* \brief Get SPI bus frequency in Hz * \brief Get SPI bus frequency in Hz
@ -196,8 +196,8 @@ inline uint32_t spi_get_frequency_div(uint8_t bus)
inline uint32_t spi_get_frequency_hz(uint8_t bus) inline uint32_t spi_get_frequency_hz(uint8_t bus)
{ {
return APB_CLK_FREQ / return APB_CLK_FREQ /
(FIELD2VAL(SPI_CLOCK_DIV_PRE, SPI(bus).CLOCK) + 1) / (FIELD2VAL(SPI_CLOCK_DIV_PRE, SPI(bus).CLOCK) + 1) /
(FIELD2VAL(SPI_CLOCK_COUNT_NUM, SPI(bus).CLOCK) + 1); (FIELD2VAL(SPI_CLOCK_COUNT_NUM, SPI(bus).CLOCK) + 1);
} }
/** /**
@ -231,7 +231,7 @@ inline spi_endianness_t spi_get_endianness(uint8_t bus)
{ {
return SPI(bus).USER0 & (SPI_USER0_WR_BYTE_ORDER | SPI_USER0_RD_BYTE_ORDER) return SPI(bus).USER0 & (SPI_USER0_WR_BYTE_ORDER | SPI_USER0_RD_BYTE_ORDER)
? SPI_BIG_ENDIAN ? SPI_BIG_ENDIAN
: SPI_LITTLE_ENDIAN; : SPI_LITTLE_ENDIAN;
} }
/** /**
@ -278,25 +278,26 @@ size_t spi_transfer(uint8_t bus, const void *out_data, void *in_data, size_t len
* \brief Add permanent command bits when transfert data over SPI * \brief Add permanent command bits when transfert data over SPI
* Example: * Example:
* *
* spi_set_command(1,1,0x01); // Set one command bit to 1 * spi_set_command(1, 1, 0x01); // Set one command bit to 1
* for (uint8_t i = 0 ; i < x ; i++ ) { * for (uint8_t i = 0; i < x; i++ ) {
* spi_transfer_8(1,0x55); // Send 1 bit command + 8 bits data x times * spi_transfer_8(1, 0x55); // Send 1 bit command + 8 bits data x times
* } * }
* spi_clear_command(1); // Clear command * spi_clear_command(1); // Clear command
* spi_transfer_8(1,0x55); // Send 8 bits data * spi_transfer_8(1, 0x55); // Send 8 bits data
* *
* \param bus Bus ID: 0 - system, 1 - user * \param bus Bus ID: 0 - system, 1 - user
* \param bits Number of bits (max: 16). * \param bits Number of bits (max: 16).
* \param data Command to send for each transfert. * \param data Command to send for each transfert.
*/ */
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
uint16_t command = data << (16-bits); //align command data to high bits SPI(bus).USER0 |= SPI_USER0_COMMAND; //enable COMMAND function in SPI module
command = ((command>>8)&0xff) | ((command<<8)&0xff00); //swap byte order uint16_t command = data << (16 - bits); //align command data to high bits
SPI(bus).USER2 = SET_FIELD(SPI(bus).USER2, SPI_USER2_COMMAND_BITLEN, --bits); command = ((command >> 8) & 0xff) | ((command << 8) & 0xff00); //swap byte order
SPI(bus).USER2 = SET_FIELD(SPI(bus).USER2, SPI_USER2_COMMAND_VALUE, command); SPI(bus).USER2 = SET_FIELD(SPI(bus).USER2, SPI_USER2_COMMAND_BITLEN, --bits);
SPI(bus).USER2 = SET_FIELD(SPI(bus).USER2, SPI_USER2_COMMAND_VALUE, command);
} }
/** /**
@ -314,11 +315,12 @@ static inline void spi_set_command(uint8_t bus,uint8_t bits, uint16_t data)
* \param bits Number of bits (max: 32). * \param bits Number of bits (max: 32).
* \param data Address to send for each transfert. * \param data Address to send for each transfert.
*/ */
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).ADDR = data<<(32-bits) ; //align address data to high bits 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); SPI(bus).USER1 = SET_FIELD(SPI(bus).USER1, SPI_USER1_ADDR_BITLEN, --bits);
} }
@ -326,12 +328,12 @@ static inline void spi_set_address(uint8_t bus,uint8_t bits, uint32_t data)
* \brief Add permanent dummy bits when transfert data over SPI * \brief Add permanent dummy bits when transfert data over SPI
* Example: * Example:
* *
* spi_set_dummy_bits(1,4,false); // Set 4 dummy bit before Dout * spi_set_dummy_bits(1, 4, false); // Set 4 dummy bit before Dout
* for (uint8_t i = 0 ; i < x ; i++ ) { * for (uint8_t i = 0; i < x; i++ ) {
* spi_transfer_16(1,0xC584); // Send 4 bits dummy + 16 bits Dout x times * spi_transfer_16(1, 0xC584); // Send 4 bits dummy + 16 bits Dout x times
* } * }
* spi_set_dummy_bits(1,4,true); // Set 4 dummy bit between Dout and Din * spi_set_dummy_bits(1, 4, true); // Set 4 dummy bit between Dout and Din
* spi_transfer_8(1,0x55); // Send 8 bits Dout + 4 bits dummy + 8 bits Din * spi_transfer_8(1, 0x55); // Send 8 bits Dout + 4 bits dummy + 8 bits Din
* *
* \param bus Bus ID: 0 - system, 1 - user * \param bus Bus ID: 0 - system, 1 - user
* \param bits Number of bits * \param bits Number of bits
@ -339,8 +341,9 @@ 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);
} }
@ -351,7 +354,7 @@ static inline void spi_set_dummy_bits(uint8_t bus, uint8_t bits, bool pos)
*/ */
static inline void spi_clear_address(uint8_t bus) static inline void spi_clear_address(uint8_t bus)
{ {
SPI(bus).USER0 &= ~(SPI_USER0_ADDR) ; SPI(bus).USER0 &= ~(SPI_USER0_ADDR);
} }
/** /**
@ -361,7 +364,7 @@ static inline void spi_clear_address(uint8_t bus)
static inline void spi_clear_command(uint8_t bus) static inline void spi_clear_command(uint8_t bus)
{ {
SPI(bus).USER0 &= ~(SPI_USER0_COMMAND) ; SPI(bus).USER0 &= ~(SPI_USER0_COMMAND);
} }
/** /**

View file

@ -20,7 +20,7 @@
#define ADDR MCP4725A0_ADDR0 #define ADDR MCP4725A0_ADDR0
#define VDD 3.3 #define VDD 3.3
inline static void wait_for_eeprom(i2c_dev_t* dev) inline static void wait_for_eeprom(i2c_dev_t *dev)
{ {
while (mcp4725_eeprom_busy(dev)) while (mcp4725_eeprom_busy(dev))
{ {

View file

@ -51,7 +51,7 @@ const float ads111x_gain_values[] = {
[ADS111X_GAIN_0V256_3] = 0.256 [ADS111X_GAIN_0V256_3] = 0.256
}; };
static uint16_t read_reg(i2c_dev_t* dev, uint8_t reg) static uint16_t read_reg(i2c_dev_t *dev, uint8_t reg)
{ {
uint16_t res = 0; uint16_t res = 0;
if (i2c_slave_read(dev->bus, dev->addr, &reg, (uint8_t *)&res, 2)) if (i2c_slave_read(dev->bus, dev->addr, &reg, (uint8_t *)&res, 2))
@ -60,7 +60,7 @@ static uint16_t read_reg(i2c_dev_t* dev, uint8_t reg)
return res; return res;
} }
static void write_reg(i2c_dev_t* dev, uint8_t reg, uint16_t val) static void write_reg(i2c_dev_t *dev, uint8_t reg, uint16_t val)
{ {
//debug("Write %d: 0x%04x", reg, val); //debug("Write %d: 0x%04x", reg, val);
uint8_t buf[2] = { val >> 8, val}; uint8_t buf[2] = { val >> 8, val};
@ -68,127 +68,127 @@ static void write_reg(i2c_dev_t* dev, uint8_t reg, uint16_t val)
debug("Could not write 0x%04x to register %d", val, reg); debug("Could not write 0x%04x to register %d", val, reg);
} }
static uint16_t read_conf_bits(i2c_dev_t* dev, uint8_t offs, uint16_t mask) static uint16_t read_conf_bits(i2c_dev_t *dev, uint8_t offs, uint16_t mask)
{ {
return (read_reg(dev, REG_CONFIG) >> offs) & mask; return (read_reg(dev, REG_CONFIG) >> offs) & mask;
} }
static void write_conf_bits(i2c_dev_t* dev, uint16_t val, uint8_t offs, uint16_t mask) static void write_conf_bits(i2c_dev_t *dev, uint16_t val, uint8_t offs, uint16_t mask)
{ {
write_reg(dev, REG_CONFIG, (read_reg(dev, REG_CONFIG) & ~(mask << offs)) | (val << offs)); write_reg(dev, REG_CONFIG, (read_reg(dev, REG_CONFIG) & ~(mask << offs)) | (val << offs));
} }
bool ads111x_busy(i2c_dev_t* dev) bool ads111x_busy(i2c_dev_t *dev)
{ {
return read_conf_bits(dev, OS_OFFSET, OS_MASK); return read_conf_bits(dev, OS_OFFSET, OS_MASK);
} }
void ads111x_start_conversion(i2c_dev_t* dev) void ads111x_start_conversion(i2c_dev_t *dev)
{ {
write_conf_bits(dev, 1, OS_OFFSET, OS_MASK); write_conf_bits(dev, 1, OS_OFFSET, OS_MASK);
} }
int16_t ads111x_get_value(i2c_dev_t* dev) int16_t ads111x_get_value(i2c_dev_t *dev)
{ {
return read_reg(dev, REG_CONVERSION); return read_reg(dev, REG_CONVERSION);
} }
ads111x_gain_t ads111x_get_gain(i2c_dev_t* dev) ads111x_gain_t ads111x_get_gain(i2c_dev_t *dev)
{ {
return read_conf_bits(dev, PGA_OFFSET, PGA_MASK); return read_conf_bits(dev, PGA_OFFSET, PGA_MASK);
} }
void ads111x_set_gain(i2c_dev_t* dev, ads111x_gain_t gain) void ads111x_set_gain(i2c_dev_t *dev, ads111x_gain_t gain)
{ {
write_conf_bits(dev, gain, PGA_OFFSET, PGA_MASK); write_conf_bits(dev, gain, PGA_OFFSET, PGA_MASK);
} }
ads111x_mux_t ads111x_get_input_mux(i2c_dev_t* dev) ads111x_mux_t ads111x_get_input_mux(i2c_dev_t *dev)
{ {
return read_conf_bits(dev, MUX_OFFSET, MUX_MASK); return read_conf_bits(dev, MUX_OFFSET, MUX_MASK);
} }
void ads111x_set_input_mux(i2c_dev_t* dev, ads111x_mux_t mux) void ads111x_set_input_mux(i2c_dev_t *dev, ads111x_mux_t mux)
{ {
write_conf_bits(dev, mux, MUX_OFFSET, MUX_MASK); write_conf_bits(dev, mux, MUX_OFFSET, MUX_MASK);
} }
ads111x_mode_t ads111x_get_mode(i2c_dev_t* dev) ads111x_mode_t ads111x_get_mode(i2c_dev_t *dev)
{ {
return read_conf_bits(dev, MODE_OFFSET, MODE_MASK); return read_conf_bits(dev, MODE_OFFSET, MODE_MASK);
} }
void ads111x_set_mode(i2c_dev_t* dev, ads111x_mode_t mode) void ads111x_set_mode(i2c_dev_t *dev, ads111x_mode_t mode)
{ {
write_conf_bits(dev, mode, MODE_OFFSET, MODE_MASK); write_conf_bits(dev, mode, MODE_OFFSET, MODE_MASK);
} }
ads111x_data_rate_t ads111x_get_data_rate(i2c_dev_t* dev) ads111x_data_rate_t ads111x_get_data_rate(i2c_dev_t *dev)
{ {
return read_conf_bits(dev, DR_OFFSET, DR_MASK); return read_conf_bits(dev, DR_OFFSET, DR_MASK);
} }
void ads111x_set_data_rate(i2c_dev_t* dev, ads111x_data_rate_t rate) void ads111x_set_data_rate(i2c_dev_t *dev, ads111x_data_rate_t rate)
{ {
write_conf_bits(dev, rate, DR_OFFSET, DR_MASK); write_conf_bits(dev, rate, DR_OFFSET, DR_MASK);
} }
ads111x_comp_mode_t ads111x_get_comp_mode(i2c_dev_t* dev) ads111x_comp_mode_t ads111x_get_comp_mode(i2c_dev_t *dev)
{ {
return read_conf_bits(dev, COMP_MODE_OFFSET, COMP_MODE_MASK); return read_conf_bits(dev, COMP_MODE_OFFSET, COMP_MODE_MASK);
} }
void ads111x_set_comp_mode(i2c_dev_t* dev, ads111x_comp_mode_t mode) void ads111x_set_comp_mode(i2c_dev_t *dev, ads111x_comp_mode_t mode)
{ {
write_conf_bits(dev, mode, COMP_MODE_OFFSET, COMP_MODE_MASK); write_conf_bits(dev, mode, COMP_MODE_OFFSET, COMP_MODE_MASK);
} }
ads111x_comp_polarity_t ads111x_get_comp_polarity(i2c_dev_t* dev) ads111x_comp_polarity_t ads111x_get_comp_polarity(i2c_dev_t *dev)
{ {
return read_conf_bits(dev, COMP_POL_OFFSET, COMP_POL_MASK); return read_conf_bits(dev, COMP_POL_OFFSET, COMP_POL_MASK);
} }
void ads111x_set_comp_polarity(i2c_dev_t* dev, ads111x_comp_polarity_t polarity) void ads111x_set_comp_polarity(i2c_dev_t *dev, ads111x_comp_polarity_t polarity)
{ {
write_conf_bits(dev, polarity, COMP_POL_OFFSET, COMP_POL_MASK); write_conf_bits(dev, polarity, COMP_POL_OFFSET, COMP_POL_MASK);
} }
ads111x_comp_latch_t ads111x_get_comp_latch(i2c_dev_t* dev) ads111x_comp_latch_t ads111x_get_comp_latch(i2c_dev_t *dev)
{ {
return read_conf_bits(dev, COMP_LAT_OFFSET, COMP_LAT_MASK); return read_conf_bits(dev, COMP_LAT_OFFSET, COMP_LAT_MASK);
} }
void ads111x_set_comp_latch(i2c_dev_t* dev, ads111x_comp_latch_t latch) void ads111x_set_comp_latch(i2c_dev_t *dev, ads111x_comp_latch_t latch)
{ {
write_conf_bits(dev, latch, COMP_LAT_OFFSET, COMP_LAT_MASK); write_conf_bits(dev, latch, COMP_LAT_OFFSET, COMP_LAT_MASK);
} }
ads111x_comp_queue_t ads111x_get_comp_queue(i2c_dev_t* dev) ads111x_comp_queue_t ads111x_get_comp_queue(i2c_dev_t *dev)
{ {
return read_conf_bits(dev, COMP_QUE_OFFSET, COMP_QUE_MASK); return read_conf_bits(dev, COMP_QUE_OFFSET, COMP_QUE_MASK);
} }
void ads111x_set_comp_queue(i2c_dev_t* dev, ads111x_comp_queue_t queue) void ads111x_set_comp_queue(i2c_dev_t *dev, ads111x_comp_queue_t queue)
{ {
write_conf_bits(dev, queue, COMP_QUE_OFFSET, COMP_QUE_MASK); write_conf_bits(dev, queue, COMP_QUE_OFFSET, COMP_QUE_MASK);
} }
int16_t ads111x_get_comp_low_thresh(i2c_dev_t* dev) int16_t ads111x_get_comp_low_thresh(i2c_dev_t *dev)
{ {
return read_reg(dev, REG_THRESH_L); return read_reg(dev, REG_THRESH_L);
} }
void ads111x_set_comp_low_thresh(i2c_dev_t* dev, int16_t thresh) void ads111x_set_comp_low_thresh(i2c_dev_t *dev, int16_t thresh)
{ {
write_reg(dev, REG_THRESH_L, thresh); write_reg(dev, REG_THRESH_L, thresh);
} }
int16_t ads111x_get_comp_high_thresh(i2c_dev_t* dev) int16_t ads111x_get_comp_high_thresh(i2c_dev_t *dev)
{ {
return read_reg(dev, REG_THRESH_H); return read_reg(dev, REG_THRESH_H);
} }
void ads111x_set_comp_high_thresh(i2c_dev_t* dev, int16_t thresh) void ads111x_set_comp_high_thresh(i2c_dev_t *dev, int16_t thresh)
{ {
write_reg(dev, REG_THRESH_H, thresh); write_reg(dev, REG_THRESH_H, thresh);
} }

View file

@ -125,20 +125,20 @@ typedef enum
* @param addr Deivce address * @param addr Deivce address
* @return true when device performing conversion * @return true when device performing conversion
*/ */
bool ads111x_busy(i2c_dev_t* dev); bool ads111x_busy(i2c_dev_t *dev);
/** /**
* Begin a single conversion (when in single-shot mode) * Begin a single conversion (when in single-shot mode)
* @param addr Deivce address * @param addr Deivce address
*/ */
void ads111x_start_conversion(i2c_dev_t* dev); void ads111x_start_conversion(i2c_dev_t *dev);
/** /**
* Read last conversion result * Read last conversion result
* @param addr * @param addr
* @return Last conversion result * @return Last conversion result
*/ */
int16_t ads111x_get_value(i2c_dev_t* dev); int16_t ads111x_get_value(i2c_dev_t *dev);
/** /**
* Read the programmable gain amplifier configuration * Read the programmable gain amplifier configuration
@ -146,70 +146,70 @@ int16_t ads111x_get_value(i2c_dev_t* dev);
* @param addr Deivce address * @param addr Deivce address
* @return Gain value * @return Gain value
*/ */
ads111x_gain_t ads111x_get_gain(i2c_dev_t* dev); ads111x_gain_t ads111x_get_gain(i2c_dev_t *dev);
/** /**
* Configure the programmable gain amplifier (ADS1114 and ADS1115 only) * Configure the programmable gain amplifier (ADS1114 and ADS1115 only)
* @param addr Deivce address * @param addr Deivce address
* @param gain Gain value * @param gain Gain value
*/ */
void ads111x_set_gain(i2c_dev_t* dev, ads111x_gain_t gain); void ads111x_set_gain(i2c_dev_t *dev, ads111x_gain_t gain);
/** /**
* Read the input multiplexer configuration (ADS1115 only) * Read the input multiplexer configuration (ADS1115 only)
* @param addr Deivce address * @param addr Deivce address
* @return Input multiplexer configuration * @return Input multiplexer configuration
*/ */
ads111x_mux_t ads111x_get_input_mux(i2c_dev_t* dev); ads111x_mux_t ads111x_get_input_mux(i2c_dev_t *dev);
/** /**
* Configure the input multiplexer configuration (ADS1115 only) * Configure the input multiplexer configuration (ADS1115 only)
* @param addr Deivce address * @param addr Deivce address
* @param mux Input multiplexer configuration * @param mux Input multiplexer configuration
*/ */
void ads111x_set_input_mux(i2c_dev_t* dev, ads111x_mux_t mux); void ads111x_set_input_mux(i2c_dev_t *dev, ads111x_mux_t mux);
/** /**
* Read the device operating mode * Read the device operating mode
* @param addr Deivce address * @param addr Deivce address
* @return Device operating mode * @return Device operating mode
*/ */
ads111x_mode_t ads111x_get_mode(i2c_dev_t* dev); ads111x_mode_t ads111x_get_mode(i2c_dev_t *dev);
/** /**
* Set the device operating mode * Set the device operating mode
* @param addr Deivce address * @param addr Deivce address
* @param mode Device operating mode * @param mode Device operating mode
*/ */
void ads111x_set_mode(i2c_dev_t* dev, ads111x_mode_t mode); void ads111x_set_mode(i2c_dev_t *dev, ads111x_mode_t mode);
/** /**
* Read the data rate * Read the data rate
* @param addr Deivce address * @param addr Deivce address
* @return Data rate * @return Data rate
*/ */
ads111x_data_rate_t ads111x_get_data_rate(i2c_dev_t* dev); ads111x_data_rate_t ads111x_get_data_rate(i2c_dev_t *dev);
/** /**
* Configure the data rate * Configure the data rate
* @param addr Deivce address * @param addr Deivce address
* @param rate Data rate * @param rate Data rate
*/ */
void ads111x_set_data_rate(i2c_dev_t* dev, ads111x_data_rate_t rate); void ads111x_set_data_rate(i2c_dev_t *dev, ads111x_data_rate_t rate);
/** /**
* Get comparator mode (ADS1114 and ADS1115 only) * Get comparator mode (ADS1114 and ADS1115 only)
* @param addr Deivce address * @param addr Deivce address
* @return Comparator mode * @return Comparator mode
*/ */
ads111x_comp_mode_t ads111x_get_comp_mode(i2c_dev_t* dev); ads111x_comp_mode_t ads111x_get_comp_mode(i2c_dev_t *dev);
/** /**
* Set comparator mode (ADS1114 and ADS1115 only) * Set comparator mode (ADS1114 and ADS1115 only)
* @param addr Deivce address * @param addr Deivce address
* @param mode Comparator mode * @param mode Comparator mode
*/ */
void ads111x_set_comp_mode(i2c_dev_t* dev, ads111x_comp_mode_t mode); void ads111x_set_comp_mode(i2c_dev_t *dev, ads111x_comp_mode_t mode);
/** /**
* Get polarity of the comparator output pin ALERT/RDY * Get polarity of the comparator output pin ALERT/RDY
@ -217,7 +217,7 @@ void ads111x_set_comp_mode(i2c_dev_t* dev, ads111x_comp_mode_t mode);
* @param addr Deivce address * @param addr Deivce address
* @return Comparator output pin polarity * @return Comparator output pin polarity
*/ */
ads111x_comp_polarity_t ads111x_get_comp_polarity(i2c_dev_t* dev); ads111x_comp_polarity_t ads111x_get_comp_polarity(i2c_dev_t *dev);
/** /**
* Set polarity of the comparator output pin ALERT/RDY * Set polarity of the comparator output pin ALERT/RDY
@ -225,7 +225,7 @@ ads111x_comp_polarity_t ads111x_get_comp_polarity(i2c_dev_t* dev);
* @param addr Deivce address * @param addr Deivce address
* @param polarity Comparator output pin polarity * @param polarity Comparator output pin polarity
*/ */
void ads111x_set_comp_polarity(i2c_dev_t* dev, ads111x_comp_polarity_t polarity); void ads111x_set_comp_polarity(i2c_dev_t *dev, ads111x_comp_polarity_t polarity);
/** /**
* Get comparator output latch mode, see datasheet. * Get comparator output latch mode, see datasheet.
@ -233,14 +233,14 @@ void ads111x_set_comp_polarity(i2c_dev_t* dev, ads111x_comp_polarity_t polarity)
* @param addr Deivce address * @param addr Deivce address
* @return Comparator output latch mode * @return Comparator output latch mode
*/ */
ads111x_comp_latch_t ads111x_get_comp_latch(i2c_dev_t* dev); ads111x_comp_latch_t ads111x_get_comp_latch(i2c_dev_t *dev);
/** /**
* Set comparator output latch mode (ADS1114 and ADS1115 only) * Set comparator output latch mode (ADS1114 and ADS1115 only)
* @param addr Deivce address * @param addr Deivce address
* @param latch Comparator output latch mode * @param latch Comparator output latch mode
*/ */
void ads111x_set_comp_latch(i2c_dev_t* dev, ads111x_comp_latch_t latch); void ads111x_set_comp_latch(i2c_dev_t *dev, ads111x_comp_latch_t latch);
/** /**
* Set number of the comparator conversions before pin ALERT/RDY * Set number of the comparator conversions before pin ALERT/RDY
@ -248,7 +248,7 @@ void ads111x_set_comp_latch(i2c_dev_t* dev, ads111x_comp_latch_t latch);
* @param addr Deivce address * @param addr Deivce address
* @return Number of the comparator conversions * @return Number of the comparator conversions
*/ */
ads111x_comp_queue_t ads111x_get_comp_queue(i2c_dev_t* dev); ads111x_comp_queue_t ads111x_get_comp_queue(i2c_dev_t *dev);
/** /**
* Get number of the comparator conversions before pin ALERT/RDY * Get number of the comparator conversions before pin ALERT/RDY
@ -256,35 +256,35 @@ ads111x_comp_queue_t ads111x_get_comp_queue(i2c_dev_t* dev);
* @param addr Deivce address * @param addr Deivce address
* @param queue Number of the comparator conversions * @param queue Number of the comparator conversions
*/ */
void ads111x_set_comp_queue(i2c_dev_t* dev, ads111x_comp_queue_t queue); void ads111x_set_comp_queue(i2c_dev_t *dev, ads111x_comp_queue_t queue);
/** /**
* Get the lower threshold value used by comparator * Get the lower threshold value used by comparator
* @param addr Deivce address * @param addr Deivce address
* @return Lower threshold value * @return Lower threshold value
*/ */
int16_t ads111x_get_comp_low_thresh(i2c_dev_t* dev); int16_t ads111x_get_comp_low_thresh(i2c_dev_t *dev);
/** /**
* Set the lower threshold value used by comparator * Set the lower threshold value used by comparator
* @param addr Deivce address * @param addr Deivce address
* @param thresh Lower threshold value * @param thresh Lower threshold value
*/ */
void ads111x_set_comp_low_thresh(i2c_dev_t* dev, int16_t thresh); void ads111x_set_comp_low_thresh(i2c_dev_t *dev, int16_t thresh);
/** /**
* Get the upper threshold value used by comparator * Get the upper threshold value used by comparator
* @param addr Deivce address * @param addr Deivce address
* @return Upper threshold value * @return Upper threshold value
*/ */
int16_t ads111x_get_comp_high_thresh(i2c_dev_t* dev); int16_t ads111x_get_comp_high_thresh(i2c_dev_t *dev);
/** /**
* Set the upper threshold value used by comparator * Set the upper threshold value used by comparator
* @param addr Deivce address * @param addr Deivce address
* @param thresh Upper threshold value * @param thresh Upper threshold value
*/ */
void ads111x_set_comp_high_thresh(i2c_dev_t* dev, int16_t thresh); void ads111x_set_comp_high_thresh(i2c_dev_t *dev, int16_t thresh);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -38,7 +38,7 @@
static int bmp180_readRegister16(i2c_dev_t *dev, uint8_t reg, int16_t *r) static int bmp180_readRegister16(i2c_dev_t *dev, uint8_t reg, int16_t *r)
{ {
uint8_t d[] = { 0, 0 }; uint8_t d[] = { 0, 0 };
int error ; int error;
if ((error = i2c_slave_read(dev->bus, dev->addr, &reg, d, 2))) if ((error = i2c_slave_read(dev->bus, dev->addr, &reg, d, 2)))
return error; return error;
@ -49,7 +49,7 @@ static int bmp180_readRegister16(i2c_dev_t *dev, uint8_t reg, int16_t *r)
static int bmp180_start_Messurement(i2c_dev_t *dev, uint8_t cmd) static int bmp180_start_Messurement(i2c_dev_t *dev, uint8_t cmd)
{ {
uint8_t reg = BMP180_CONTROL_REG ; uint8_t reg = BMP180_CONTROL_REG;
return i2c_slave_write(dev->bus, dev->addr, &reg, &cmd, 1); return i2c_slave_write(dev->bus, dev->addr, &reg, &cmd, 1);
} }

View file

@ -60,12 +60,12 @@ void bmp280_init_default_params(bmp280_params_t *params)
params->mode = BMP280_MODE_NORMAL; params->mode = BMP280_MODE_NORMAL;
params->filter = BMP280_FILTER_OFF; params->filter = BMP280_FILTER_OFF;
params->oversampling_pressure = BMP280_STANDARD; params->oversampling_pressure = BMP280_STANDARD;
params->oversampling_temperature = BMP280_STANDARD ; params->oversampling_temperature = BMP280_STANDARD;
params->oversampling_humidity = BMP280_STANDARD; params->oversampling_humidity = BMP280_STANDARD;
params->standby = BMP280_STANDBY_250; params->standby = BMP280_STANDBY_250;
} }
static bool read_register16(i2c_dev_t* dev, uint8_t addr, uint16_t *value) static bool read_register16(i2c_dev_t *dev, uint8_t addr, uint16_t *value)
{ {
uint8_t d[] = {0, 0}; uint8_t d[] = {0, 0};
if (!i2c_slave_read(dev->bus, dev->addr, &addr, d, sizeof(d))) { if (!i2c_slave_read(dev->bus, dev->addr, &addr, d, sizeof(d))) {
@ -75,7 +75,7 @@ static bool read_register16(i2c_dev_t* dev, uint8_t addr, uint16_t *value)
return false; return false;
} }
static inline int read_data(i2c_dev_t* dev, uint8_t addr, uint8_t *value, uint8_t len) static inline int read_data(i2c_dev_t *dev, uint8_t addr, uint8_t *value, uint8_t len)
{ {
return i2c_slave_read(dev->bus, dev->addr, &addr, value, len); return i2c_slave_read(dev->bus, dev->addr, &addr, value, len);
} }
@ -141,7 +141,7 @@ static bool read_hum_calibration_data(bmp280_t *dev)
return false; return false;
} }
static int write_register8(i2c_dev_t* dev, uint8_t addr, uint8_t value) static int write_register8(i2c_dev_t *dev, uint8_t addr, uint8_t value)
{ {
return i2c_slave_write(dev->bus, dev->addr, &addr, &value, 1); return i2c_slave_write(dev->bus, dev->addr, &addr, &value, 1);
} }

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

@ -38,36 +38,36 @@ static uint8_t dec2bcd(uint8_t val)
return ((val / 10) << 4) + (val % 10); return ((val / 10) << 4) + (val % 10);
} }
static uint8_t read_register(i2c_dev_t* dev, uint8_t reg) static uint8_t read_register(i2c_dev_t *dev, uint8_t reg)
{ {
uint8_t val; uint8_t val;
i2c_slave_read(dev->bus, dev->addr, &reg, &val, 1); i2c_slave_read(dev->bus, dev->addr, &reg, &val, 1);
return val; return val;
} }
static void update_register(i2c_dev_t* dev, uint8_t reg, uint8_t mask, uint8_t val) static void update_register(i2c_dev_t *dev, uint8_t reg, uint8_t mask, uint8_t val)
{ {
uint8_t buf = (read_register(dev,reg) & mask) | val; uint8_t buf = (read_register(dev, reg) & mask) | val;
i2c_slave_write(dev->bus, dev->addr, &reg, &buf, 1); i2c_slave_write(dev->bus, dev->addr, &reg, &buf, 1);
} }
void ds1307_start(i2c_dev_t* dev, bool start) void ds1307_start(i2c_dev_t *dev, bool start)
{ {
update_register(dev, TIME_REG, CH_MASK, start ? 0 : CH_BIT); update_register(dev, TIME_REG, CH_MASK, start ? 0 : CH_BIT);
} }
bool ds1307_is_running(i2c_dev_t* dev) bool ds1307_is_running(i2c_dev_t *dev)
{ {
return !(read_register(dev, TIME_REG) & CH_BIT); return !(read_register(dev, TIME_REG) & CH_BIT);
} }
void ds1307_get_time(i2c_dev_t* dev, struct tm *time) void ds1307_get_time(i2c_dev_t *dev, struct tm *time)
{ {
uint8_t buf[7]; uint8_t buf[7];
uint8_t reg = TIME_REG ; uint8_t reg = TIME_REG;
i2c_slave_read(dev->bus, dev->addr, &reg , buf, 7); i2c_slave_read(dev->bus, dev->addr, &reg, buf, 7);
time->tm_sec = bcd2dec(buf[0] & SECONDS_MASK); time->tm_sec = bcd2dec(buf[0] & SECONDS_MASK);
time->tm_min = bcd2dec(buf[1]); time->tm_min = bcd2dec(buf[1]);
@ -78,14 +78,15 @@ 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;
time->tm_year = bcd2dec(buf[6]) + 2000; time->tm_year = bcd2dec(buf[6]) + 2000;
} }
void ds1307_set_time(i2c_dev_t* dev, const struct tm *time) void ds1307_set_time(i2c_dev_t *dev, const struct tm *time)
{ {
uint8_t buf[8]; uint8_t buf[8];
buf[0] = TIME_REG; buf[0] = TIME_REG;
@ -97,51 +98,55 @@ void ds1307_set_time(i2c_dev_t* dev, const struct tm *time)
buf[6] = dec2bcd(time->tm_mon + 1); buf[6] = dec2bcd(time->tm_mon + 1);
buf[7] = dec2bcd(time->tm_year - 2000); buf[7] = dec2bcd(time->tm_year - 2000);
i2c_slave_write(dev->bus, dev->addr, &buf[0], &buf[1] , 7); i2c_slave_write(dev->bus, dev->addr, &buf[0], &buf[1], 7);
} }
void ds1307_enable_squarewave(i2c_dev_t* dev, bool enable) void ds1307_enable_squarewave(i2c_dev_t *dev, bool enable)
{ {
update_register(dev, CONTROL_REG, SQWE_MASK, enable ? SQWE_BIT : 0); update_register(dev, CONTROL_REG, SQWE_MASK, enable ? SQWE_BIT : 0);
} }
bool ds1307_is_squarewave_enabled(i2c_dev_t* dev) bool ds1307_is_squarewave_enabled(i2c_dev_t *dev)
{ {
return read_register(dev, CONTROL_REG) & SQWE_BIT; return read_register(dev, CONTROL_REG) & SQWE_BIT;
} }
void ds1307_set_squarewave_freq(i2c_dev_t* dev, ds1307_squarewave_freq_t freq) void ds1307_set_squarewave_freq(i2c_dev_t *dev, ds1307_squarewave_freq_t freq)
{ {
update_register(dev, CONTROL_REG, SQWEF_MASK, (uint8_t)freq); update_register(dev, CONTROL_REG, SQWEF_MASK, (uint8_t)freq);
} }
ds1307_squarewave_freq_t ds1307_get_squarewave_freq(i2c_dev_t* dev) ds1307_squarewave_freq_t ds1307_get_squarewave_freq(i2c_dev_t *dev)
{ {
return (ds1307_squarewave_freq_t)(read_register(dev, CONTROL_REG) & SQWEF_MASK); return (ds1307_squarewave_freq_t)(read_register(dev, CONTROL_REG) & SQWEF_MASK);
} }
bool ds1307_get_output(i2c_dev_t* dev) bool ds1307_get_output(i2c_dev_t *dev)
{ {
return read_register(dev, CONTROL_REG) & OUT_BIT; return read_register(dev, CONTROL_REG) & OUT_BIT;
} }
void ds1307_set_output(i2c_dev_t* dev, bool value) void ds1307_set_output(i2c_dev_t *dev, bool value)
{ {
update_register(dev, CONTROL_REG, OUT_MASK, value ? OUT_BIT : 0); update_register(dev, CONTROL_REG, OUT_MASK, value ? OUT_BIT : 0);
} }
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)
uint8_t reg = RAM_REG + offset ; return -EINVAL;
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);
} }
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)
uint8_t reg = RAM_REG + offset ; return -EINVAL;
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

@ -17,11 +17,12 @@
extern "C" { 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
@ -33,62 +34,62 @@ typedef enum _ds1307_squarewave_freq_t
* \brief Start/stop clock * \brief Start/stop clock
* \param start Start clock if true * \param start Start clock if true
*/ */
void ds1307_start(i2c_dev_t* dev, bool start); void ds1307_start(i2c_dev_t *dev, bool start);
/** /**
* \brief Get current clock state * \brief Get current clock state
* \return true if clock running * \return true if clock running
*/ */
bool ds1307_is_running(i2c_dev_t* dev); bool ds1307_is_running(i2c_dev_t *dev);
/** /**
* \brief Get current time * \brief Get current time
* \param time Pointer to the time struct to fill * \param time Pointer to the time struct to fill
*/ */
void ds1307_get_time(i2c_dev_t* dev, struct tm *time); void ds1307_get_time(i2c_dev_t *dev, struct tm *time);
/** /**
* \brief Set time to RTC * \brief Set time to RTC
* \param time Pointer to the time struct * \param time Pointer to the time struct
*/ */
void ds1307_set_time(i2c_dev_t* dev, const struct tm *time); void ds1307_set_time(i2c_dev_t *dev, const struct tm *time);
/** /**
* \brief Enable or disable square-wave oscillator output * \brief Enable or disable square-wave oscillator output
* \param enable Enable oscillator if true * \param enable Enable oscillator if true
*/ */
void ds1307_enable_squarewave(i2c_dev_t* dev, bool enable); void ds1307_enable_squarewave(i2c_dev_t *dev, bool enable);
/** /**
* \brief Get square-wave oscillator output * \brief Get square-wave oscillator output
* \return true if square-wave oscillator enabled * \return true if square-wave oscillator enabled
*/ */
bool ds1307_is_squarewave_enabled(i2c_dev_t* dev); bool ds1307_is_squarewave_enabled(i2c_dev_t *dev);
/** /**
* \brief Set square-wave oscillator frequency * \brief Set square-wave oscillator frequency
* \param freq Frequency * \param freq Frequency
*/ */
void ds1307_set_squarewave_freq(i2c_dev_t* dev, ds1307_squarewave_freq_t freq); void ds1307_set_squarewave_freq(i2c_dev_t *dev, ds1307_squarewave_freq_t freq);
/** /**
* \brief Get current square-wave oscillator frequency * \brief Get current square-wave oscillator frequency
* \return Frequency * \return Frequency
*/ */
ds1307_squarewave_freq_t ds1307_get_squarewave_freq(i2c_dev_t* dev); ds1307_squarewave_freq_t ds1307_get_squarewave_freq(i2c_dev_t *dev);
/** /**
* \brief Get current output level of the SQW/OUT pin * \brief Get current output level of the SQW/OUT pin
* \return true if high * \return true if high
*/ */
bool ds1307_get_output(i2c_dev_t* dev); bool ds1307_get_output(i2c_dev_t *dev);
/** /**
* \brief Set output level of the SQW/OUT pin * \brief Set output level of the SQW/OUT pin
* Set output level if square-wave output is disabled * Set output level if square-wave output is disabled
* \param value High level if true * \param value High level if true
*/ */
void ds1307_set_output(i2c_dev_t* dev, bool value); void ds1307_set_output(i2c_dev_t *dev, bool value);
/** /**
* \brief Read RAM contents into the buffer * \brief Read RAM contents into the buffer
@ -97,7 +98,7 @@ void ds1307_set_output(i2c_dev_t* dev, bool value);
* \param len Bytes to read, 1..56 * \param len Bytes to read, 1..56
* \return Non-zero if error occured * \return Non-zero if error occured
*/ */
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);
/** /**
* \brief Write buffer to RTC RAM * \brief Write buffer to RTC RAM
@ -106,7 +107,7 @@ int ds1307_read_ram(i2c_dev_t* dev, uint8_t offset, uint8_t *buf, uint8_t len);
* \param len Bytes to write, 1..56 * \param len Bytes to write, 1..56
* \return Non-zero if error occured * \return Non-zero if error occured
*/ */
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);
#ifdef __cplusplus #ifdef __cplusplus

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

@ -52,24 +52,24 @@ static const float gain_values [] = {
static float current_gain; static float current_gain;
static hmc5883l_operating_mode_t current_mode; static hmc5883l_operating_mode_t current_mode;
static inline void write_register(i2c_dev_t* dev, uint8_t reg, uint8_t val) static inline void write_register(i2c_dev_t *dev, uint8_t reg, uint8_t val)
{ {
i2c_slave_write(dev->bus, dev->addr, &reg, &val, 1); i2c_slave_write(dev->bus, dev->addr, &reg, &val, 1);
} }
static inline uint8_t read_register(i2c_dev_t* dev, uint8_t reg) static inline uint8_t read_register(i2c_dev_t *dev, uint8_t reg)
{ {
uint8_t res; uint8_t res;
i2c_slave_read(dev->bus, dev->addr, &reg, &res, 1); i2c_slave_read(dev->bus, dev->addr, &reg, &res, 1);
return res; return res;
} }
static inline void update_register(i2c_dev_t* dev, uint8_t reg, uint8_t mask, uint8_t val) static inline void update_register(i2c_dev_t *dev, uint8_t reg, uint8_t mask, uint8_t val)
{ {
write_register(dev, reg, (read_register(dev, reg) & mask) | val); write_register(dev, reg, (read_register(dev, reg) & mask) | val);
} }
bool hmc5883l_init(i2c_dev_t* dev) bool hmc5883l_init(i2c_dev_t *dev)
{ {
if (hmc5883l_get_id(dev) != HMC5883L_ID) if (hmc5883l_get_id(dev) != HMC5883L_ID)
return false; return false;
@ -78,7 +78,7 @@ bool hmc5883l_init(i2c_dev_t* dev)
return true; return true;
} }
uint32_t hmc5883l_get_id(i2c_dev_t* dev) uint32_t hmc5883l_get_id(i2c_dev_t *dev)
{ {
uint32_t res = 0; uint32_t res = 0;
uint8_t reg = REG_ID_A; uint8_t reg = REG_ID_A;
@ -86,70 +86,70 @@ uint32_t hmc5883l_get_id(i2c_dev_t* dev)
return res; return res;
} }
hmc5883l_operating_mode_t hmc5883l_get_operating_mode(i2c_dev_t* dev) hmc5883l_operating_mode_t hmc5883l_get_operating_mode(i2c_dev_t *dev)
{ {
uint8_t res = read_register(dev, REG_MODE) & MASK_MD; uint8_t res = read_register(dev, REG_MODE) & MASK_MD;
return res == 0 ? HMC5883L_MODE_CONTINUOUS : HMC5883L_MODE_SINGLE; return res == 0 ? HMC5883L_MODE_CONTINUOUS : HMC5883L_MODE_SINGLE;
} }
void hmc5883l_set_operating_mode(i2c_dev_t* dev, hmc5883l_operating_mode_t mode) void hmc5883l_set_operating_mode(i2c_dev_t *dev, hmc5883l_operating_mode_t mode)
{ {
write_register(dev, REG_MODE, mode); write_register(dev, REG_MODE, mode);
current_mode = mode; current_mode = mode;
} }
hmc5883l_samples_averaged_t hmc5883l_get_samples_averaged(i2c_dev_t* dev) hmc5883l_samples_averaged_t hmc5883l_get_samples_averaged(i2c_dev_t *dev)
{ {
return (read_register(dev, REG_CR_A) & MASK_MA) >> BIT_MA; return (read_register(dev, REG_CR_A) & MASK_MA) >> BIT_MA;
} }
void hmc5883l_set_samples_averaged(i2c_dev_t* dev, hmc5883l_samples_averaged_t samples) void hmc5883l_set_samples_averaged(i2c_dev_t *dev, hmc5883l_samples_averaged_t samples)
{ {
update_register(dev, REG_CR_A, MASK_MA, samples << BIT_MA); update_register(dev, REG_CR_A, MASK_MA, samples << BIT_MA);
} }
hmc5883l_data_rate_t hmc5883l_get_data_rate(i2c_dev_t* dev) hmc5883l_data_rate_t hmc5883l_get_data_rate(i2c_dev_t *dev)
{ {
return (read_register(dev, REG_CR_A) & MASK_DO) >> BIT_DO; return (read_register(dev, REG_CR_A) & MASK_DO) >> BIT_DO;
} }
void hmc5883l_set_data_rate(i2c_dev_t* dev, hmc5883l_data_rate_t rate) void hmc5883l_set_data_rate(i2c_dev_t *dev, hmc5883l_data_rate_t rate)
{ {
update_register(dev, REG_CR_A, MASK_DO, rate << BIT_DO); update_register(dev, REG_CR_A, MASK_DO, rate << BIT_DO);
} }
hmc5883l_bias_t hmc5883l_get_bias(i2c_dev_t* dev) hmc5883l_bias_t hmc5883l_get_bias(i2c_dev_t *dev)
{ {
return read_register(dev, REG_CR_A) & MASK_MS; return read_register(dev, REG_CR_A) & MASK_MS;
} }
void hmc5883l_set_bias(i2c_dev_t* dev, hmc5883l_bias_t bias) void hmc5883l_set_bias(i2c_dev_t *dev, hmc5883l_bias_t bias)
{ {
update_register(dev, REG_CR_A, MASK_MS, bias); update_register(dev, REG_CR_A, MASK_MS, bias);
} }
hmc5883l_gain_t hmc5883l_get_gain(i2c_dev_t* dev) hmc5883l_gain_t hmc5883l_get_gain(i2c_dev_t *dev)
{ {
return read_register(dev, REG_CR_B) >> BIT_GN; return read_register(dev, REG_CR_B) >> BIT_GN;
} }
void hmc5883l_set_gain(i2c_dev_t* dev, hmc5883l_gain_t gain) void hmc5883l_set_gain(i2c_dev_t *dev, hmc5883l_gain_t gain)
{ {
write_register(dev, REG_CR_B, gain << BIT_GN); write_register(dev, REG_CR_B, gain << BIT_GN);
current_gain = gain_values[gain]; current_gain = gain_values[gain];
} }
bool hmc5883l_data_is_locked(i2c_dev_t* dev) bool hmc5883l_data_is_locked(i2c_dev_t *dev)
{ {
return read_register(dev, REG_STAT) & MASK_DL; return read_register(dev, REG_STAT) & MASK_DL;
} }
bool hmc5883l_data_is_ready(i2c_dev_t* dev) bool hmc5883l_data_is_ready(i2c_dev_t *dev)
{ {
return read_register(dev, REG_STAT) & MASK_DR; return read_register(dev, REG_STAT) & MASK_DR;
} }
bool hmc5883l_get_raw_data(i2c_dev_t* dev, hmc5883l_raw_data_t *data) bool hmc5883l_get_raw_data(i2c_dev_t *dev, hmc5883l_raw_data_t *data)
{ {
if (current_mode == HMC5883L_MODE_SINGLE) if (current_mode == HMC5883L_MODE_SINGLE)
{ {
@ -179,7 +179,7 @@ void hmc5883l_raw_to_mg(const hmc5883l_raw_data_t *raw, hmc5883l_data_t *mg)
mg->z = raw->z * current_gain; mg->z = raw->z * current_gain;
} }
bool hmc5883l_get_data(i2c_dev_t* dev, hmc5883l_data_t *data) bool hmc5883l_get_data(i2c_dev_t *dev, hmc5883l_data_t *data)
{ {
hmc5883l_raw_data_t raw; hmc5883l_raw_data_t raw;

View file

@ -104,82 +104,82 @@ typedef struct
* \brief Init device * \brief Init device
* \return false if error occured * \return false if error occured
*/ */
bool hmc5883l_init(i2c_dev_t* dev); bool hmc5883l_init(i2c_dev_t *dev);
/** /**
* \brief Get device ID * \brief Get device ID
* Always returns 0x00333448 if IC functioning properly. * Always returns 0x00333448 if IC functioning properly.
* \return Device ID * \return Device ID
*/ */
uint32_t hmc5883l_get_id(i2c_dev_t* dev); uint32_t hmc5883l_get_id(i2c_dev_t *dev);
/** /**
* \brief Get operating mode * \brief Get operating mode
* \return Measurement mode * \return Measurement mode
*/ */
hmc5883l_operating_mode_t hmc5883l_get_operating_mode(i2c_dev_t* dev); hmc5883l_operating_mode_t hmc5883l_get_operating_mode(i2c_dev_t *dev);
/** /**
* \brief Set operating mode * \brief Set operating mode
* \param mode Measurement mode * \param mode Measurement mode
*/ */
void hmc5883l_set_operating_mode(i2c_dev_t* dev, hmc5883l_operating_mode_t mode); void hmc5883l_set_operating_mode(i2c_dev_t *dev, hmc5883l_operating_mode_t mode);
/** /**
* \brief Get number of samples averaged per measurement output * \brief Get number of samples averaged per measurement output
* \return Number of samples * \return Number of samples
*/ */
hmc5883l_samples_averaged_t hmc5883l_get_samples_averaged(i2c_dev_t* dev); hmc5883l_samples_averaged_t hmc5883l_get_samples_averaged(i2c_dev_t *dev);
/** /**
* \brief Set number of samples averaged per measurement output * \brief Set number of samples averaged per measurement output
* \param samples Number of samples * \param samples Number of samples
*/ */
void hmc5883l_set_samples_averaged(i2c_dev_t* dev, hmc5883l_samples_averaged_t samples); void hmc5883l_set_samples_averaged(i2c_dev_t *dev, hmc5883l_samples_averaged_t samples);
/** /**
* \brief Get data output rate in continuous measurement mode * \brief Get data output rate in continuous measurement mode
* \return Data output rate * \return Data output rate
*/ */
hmc5883l_data_rate_t hmc5883l_get_data_rate(i2c_dev_t* dev); hmc5883l_data_rate_t hmc5883l_get_data_rate(i2c_dev_t *dev);
/** /**
* \brief Set data output rate in continuous measurement mode * \brief Set data output rate in continuous measurement mode
* \param rate Data output rate * \param rate Data output rate
*/ */
void hmc5883l_set_data_rate(i2c_dev_t* dev, hmc5883l_data_rate_t rate); void hmc5883l_set_data_rate(i2c_dev_t *dev, hmc5883l_data_rate_t rate);
/** /**
* \brief Get measurement mode (bias of the axes) * \brief Get measurement mode (bias of the axes)
* See datasheet for self test description * See datasheet for self test description
* \return Bias * \return Bias
*/ */
hmc5883l_bias_t hmc5883l_get_bias(i2c_dev_t* dev); hmc5883l_bias_t hmc5883l_get_bias(i2c_dev_t *dev);
/** /**
* \brief Set measurement mode (bias of the axes) * \brief Set measurement mode (bias of the axes)
* See datasheet for self test description * See datasheet for self test description
* \param bias Bias * \param bias Bias
*/ */
void hmc5883l_set_bias(i2c_dev_t* dev, hmc5883l_bias_t bias); void hmc5883l_set_bias(i2c_dev_t *dev, hmc5883l_bias_t bias);
/** /**
* \brief Get device gain * \brief Get device gain
* \return Current gain * \return Current gain
*/ */
hmc5883l_gain_t hmc5883l_get_gain(i2c_dev_t* dev); hmc5883l_gain_t hmc5883l_get_gain(i2c_dev_t *dev);
/** /**
* \brief Set device gain * \brief Set device gain
* \param gain Gain * \param gain Gain
*/ */
void hmc5883l_set_gain(i2c_dev_t* dev, hmc5883l_gain_t gain); void hmc5883l_set_gain(i2c_dev_t *dev, hmc5883l_gain_t gain);
/** /**
* \brief Get data state * \brief Get data state
* \return true when data is written to all six data registers * \return true when data is written to all six data registers
*/ */
bool hmc5883l_data_is_ready(i2c_dev_t* dev); bool hmc5883l_data_is_ready(i2c_dev_t *dev);
/** /**
* \brief Get lock state. * \brief Get lock state.
@ -191,14 +191,14 @@ bool hmc5883l_data_is_ready(i2c_dev_t* dev);
* 4. power is reset. * 4. power is reset.
* \return true when data registers is locked * \return true when data registers is locked
*/ */
bool hmc5883l_data_is_locked(i2c_dev_t* dev); bool hmc5883l_data_is_locked(i2c_dev_t *dev);
/** /**
* \brief Get raw magnetic data * \brief Get raw magnetic data
* \param data Pointer to the struct to write raw data * \param data Pointer to the struct to write raw data
* \return false if error occured in single measurement mode, always true in continuous mode * \return false if error occured in single measurement mode, always true in continuous mode
*/ */
bool hmc5883l_get_raw_data(i2c_dev_t* dev, hmc5883l_raw_data_t *data); bool hmc5883l_get_raw_data(i2c_dev_t *dev, hmc5883l_raw_data_t *data);
/** /**
* \brief Convert raw magnetic data to milligausses * \brief Convert raw magnetic data to milligausses
@ -212,7 +212,7 @@ void hmc5883l_raw_to_mg(const hmc5883l_raw_data_t *raw, hmc5883l_data_t *mg);
* \param data Pointer to the struct to write data * \param data Pointer to the struct to write data
* \return false if error occured in single measurement mode, always true in continuous mode * \return false if error occured in single measurement mode, always true in continuous mode
*/ */
bool hmc5883l_get_data(i2c_dev_t* dev, hmc5883l_data_t *data); bool hmc5883l_get_data(i2c_dev_t *dev, hmc5883l_data_t *data);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -18,20 +18,20 @@
#define debug(fmt, ...) #define debug(fmt, ...)
#endif #endif
static int _wireWriteRegister (const i2c_dev_t* dev, uint8_t reg, uint16_t value) static int _wireWriteRegister(const i2c_dev_t *dev, uint8_t reg, uint16_t value)
{ {
uint8_t d[2] = { 0 , 0 }; uint8_t d[2] = { 0, 0 };
d[1] = value & 0x00FF; d[1] = value & 0x00FF;
d[0] = (value >> 8) & 0x00FF; d[0] = (value >> 8) & 0x00FF;
debug("Data write to bus %u at %02X : %02X+%04X\n",dev->bus, dev->addr, reg, value); debug("Data write to bus %u at %02X : %02X+%04X\n", dev->bus, dev->addr, reg, value);
return i2c_slave_write(dev->bus, dev->addr, &reg, d, sizeof(d)); return i2c_slave_write(dev->bus, dev->addr, &reg, d, sizeof(d));
} }
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,21 +53,23 @@ 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;
} }
return 0; return 0;
} }
int ina3221_setting(ina3221_t *dev ,bool mode, bool bus, bool shunt) int ina3221_setting(ina3221_t *dev, bool mode, bool bus, bool shunt)
{ {
dev->config.mode = mode; dev->config.mode = mode;
dev->config.ebus = bus; dev->config.ebus = bus;
@ -75,7 +77,7 @@ int ina3221_setting(ina3221_t *dev ,bool mode, bool bus, bool shunt)
return _wireWriteRegister(&dev->i2c_dev, INA3221_REG_CONFIG, dev->config.config_register); return _wireWriteRegister(&dev->i2c_dev, INA3221_REG_CONFIG, dev->config.config_register);
} }
int ina3221_enableChannel(ina3221_t *dev ,bool ch1, bool ch2, bool ch3) int ina3221_enableChannel(ina3221_t *dev, bool ch1, bool ch2, bool ch3)
{ {
dev->config.ch1 = ch1; dev->config.ch1 = ch1;
dev->config.ch2 = ch2; dev->config.ch2 = ch2;
@ -83,7 +85,7 @@ int ina3221_enableChannel(ina3221_t *dev ,bool ch1, bool ch2, bool ch3)
return _wireWriteRegister(&dev->i2c_dev, INA3221_REG_CONFIG, dev->config.config_register); return _wireWriteRegister(&dev->i2c_dev, INA3221_REG_CONFIG, dev->config.config_register);
} }
int ina3221_enableChannelSum(ina3221_t *dev ,bool ch1, bool ch2, bool ch3) int ina3221_enableChannelSum(ina3221_t *dev, bool ch1, bool ch2, bool ch3)
{ {
dev->mask.scc1 = ch1; dev->mask.scc1 = ch1;
dev->mask.scc2 = ch2; dev->mask.scc2 = ch2;
@ -91,7 +93,7 @@ int ina3221_enableChannelSum(ina3221_t *dev ,bool ch1, bool ch2, bool ch3)
return _wireWriteRegister(&dev->i2c_dev, INA3221_REG_MASK, dev->mask.mask_register & INA3221_MASK_CONFIG); return _wireWriteRegister(&dev->i2c_dev, INA3221_REG_MASK, dev->mask.mask_register & INA3221_MASK_CONFIG);
} }
int ina3221_enableLatchPin(ina3221_t *dev ,bool warning, bool critical) int ina3221_enableLatchPin(ina3221_t *dev, bool warning, bool critical)
{ {
dev->mask.wen = warning; dev->mask.wen = warning;
dev->mask.cen = critical; dev->mask.cen = critical;
@ -104,13 +106,13 @@ int ina3221_setAverage(ina3221_t *dev, ina3221_avg_t avg)
return _wireWriteRegister(&dev->i2c_dev, INA3221_REG_CONFIG, dev->config.config_register); return _wireWriteRegister(&dev->i2c_dev, INA3221_REG_CONFIG, dev->config.config_register);
} }
int ina3221_setBusConversionTime(ina3221_t *dev,ina3221_ct_t ct) int ina3221_setBusConversionTime(ina3221_t *dev, ina3221_ct_t ct)
{ {
dev->config.vbus = ct; dev->config.vbus = ct;
return _wireWriteRegister(&dev->i2c_dev, INA3221_REG_CONFIG, dev->config.config_register); return _wireWriteRegister(&dev->i2c_dev, INA3221_REG_CONFIG, dev->config.config_register);
} }
int ina3221_setShuntConversionTime(ina3221_t *dev,ina3221_ct_t ct) int ina3221_setShuntConversionTime(ina3221_t *dev, ina3221_ct_t ct)
{ {
dev->config.vsht = ct; dev->config.vsht = ct;
return _wireWriteRegister(&dev->i2c_dev, INA3221_REG_CONFIG, dev->config.config_register); return _wireWriteRegister(&dev->i2c_dev, INA3221_REG_CONFIG, dev->config.config_register);
@ -118,9 +120,9 @@ int ina3221_setShuntConversionTime(ina3221_t *dev,ina3221_ct_t ct)
int ina3221_reset(ina3221_t *dev) int ina3221_reset(ina3221_t *dev)
{ {
dev->config.config_register = INA3221_DEFAULT_CONFIG ; //dev reset dev->config.config_register = INA3221_DEFAULT_CONFIG; //dev reset
dev->mask.mask_register = INA3221_DEFAULT_CONFIG ; //dev reset dev->mask.mask_register = INA3221_DEFAULT_CONFIG; //dev reset
dev->config.rst = 1 ; dev->config.rst = 1;
return _wireWriteRegister(&dev->i2c_dev, INA3221_REG_CONFIG, dev->config.config_register); // send reset to device return _wireWriteRegister(&dev->i2c_dev, INA3221_REG_CONFIG, dev->config.config_register); // send reset to device
} }
@ -128,74 +130,74 @@ int ina3221_getBusVoltage(ina3221_t *dev, ina3221_channel_t channel, float *volt
{ {
int16_t raw_value; int16_t raw_value;
int err = 0; int err = 0;
if ((err = _wireReadRegister(&dev->i2c_dev,INA3221_REG_BUSVOLTAGE_1+channel*2, (uint16_t*)&raw_value))) if ((err = _wireReadRegister(&dev->i2c_dev, INA3221_REG_BUSVOLTAGE_1 + channel * 2, (uint16_t*)&raw_value)))
return err; return err;
*voltage = raw_value*0.001 ; //V 8mV step *voltage = raw_value * 0.001; //V 8mV step
return 0; return 0;
} }
int ina3221_getShuntValue(ina3221_t *dev, ina3221_channel_t channel, float *voltage, float *current) int ina3221_getShuntValue(ina3221_t *dev, ina3221_channel_t channel, float *voltage, float *current)
{ {
int16_t raw_value; int16_t raw_value;
int err = 0; int err = 0;
if ((err = _wireReadRegister(&dev->i2c_dev,INA3221_REG_SHUNTVOLTAGE_1+channel*2, (uint16_t*)&raw_value))) if ((err = _wireReadRegister(&dev->i2c_dev, INA3221_REG_SHUNTVOLTAGE_1 + channel * 2, (uint16_t*)&raw_value)))
return err; return err;
*voltage = raw_value*0.005; //mV 40uV step *voltage = raw_value * 0.005; //mV 40uV step
if(!dev->shunt[channel]) if (!dev->shunt[channel])
{ {
debug("No shunt configured for channel %u. Dev:%u:%X\n",channel+1, dev->bus, dev->addr); debug("No shunt configured for channel %u. Dev:%u:%X\n", channel+1, dev->bus, dev->addr);
return -EINVAL; return -EINVAL;
} }
*current = (*voltage*1000.0)/dev->shunt[channel] ; //mA *current = (*voltage * 1000.0) / dev->shunt[channel]; //mA
return 0; return 0;
} }
int ina3221_getSumShuntValue(ina3221_t *dev, float *voltage) int ina3221_getSumShuntValue(ina3221_t *dev, float *voltage)
{ {
int16_t raw_value; int16_t raw_value;
int err = 0; int err = 0;
if ((err = _wireReadRegister(&dev->i2c_dev,INA3221_REG_SHUNT_VOLTAGE_SUM, (uint16_t*)&raw_value))) if ((err = _wireReadRegister(&dev->i2c_dev, INA3221_REG_SHUNT_VOLTAGE_SUM, (uint16_t*)&raw_value)))
return err; return err;
*voltage = raw_value*0.02; //uV 40uV step *voltage = raw_value * 0.02; //uV 40uV step
return 0; return 0;
} }
int ina3221_setCriticalAlert(ina3221_t *dev, ina3221_channel_t channel, float current) int ina3221_setCriticalAlert(ina3221_t *dev, ina3221_channel_t channel, float current)
{ {
int16_t raw_value = current*dev->shunt[channel]*0.2; // format int16_t raw_value = current * dev->shunt[channel] * 0.2; // format
return _wireWriteRegister(&dev->i2c_dev,INA3221_REG_CRITICAL_ALERT_1+channel*2, *(uint16_t*)&raw_value); return _wireWriteRegister(&dev->i2c_dev, INA3221_REG_CRITICAL_ALERT_1 + channel * 2, *(uint16_t*)&raw_value);
} }
int ina3221_setWarningAlert(ina3221_t *dev, ina3221_channel_t channel, float current) int ina3221_setWarningAlert(ina3221_t *dev, ina3221_channel_t channel, float current)
{ {
int16_t raw_value = current*dev->shunt[channel]*0.2 ; // format int16_t raw_value = current * dev->shunt[channel] * 0.2; // format
return _wireWriteRegister(&dev->i2c_dev,INA3221_REG_WARNING_ALERT_1+channel*2, *(uint16_t*)&raw_value); return _wireWriteRegister(&dev->i2c_dev, INA3221_REG_WARNING_ALERT_1 + channel * 2, *(uint16_t*)&raw_value);
} }
int ina3221_setSumWarningAlert(ina3221_t *dev, float voltage) int ina3221_setSumWarningAlert(ina3221_t *dev, float voltage)
{ {
int16_t raw_value = voltage*50.0 ; // format int16_t raw_value = voltage * 50.0; // format
return _wireWriteRegister(&dev->i2c_dev,INA3221_REG_SHUNT_VOLTAGE_SUM_LIMIT, *(uint16_t*)&raw_value); return _wireWriteRegister(&dev->i2c_dev, INA3221_REG_SHUNT_VOLTAGE_SUM_LIMIT, *(uint16_t*)&raw_value);
} }
int ina3221_setPowerValidUpperLimit(ina3221_t *dev, float voltage) int ina3221_setPowerValidUpperLimit(ina3221_t *dev, float voltage)
{ {
if(!dev->config.ebus) if (!dev->config.ebus)
{ {
debug("Bus not enable. Dev:%u:%X\n", dev->bus, dev->addr); debug("Bus not enable. Dev:%u:%X\n", dev->bus, dev->addr);
return -ENOTSUP; return -ENOTSUP;
} }
int16_t raw_value = voltage*1000.0; //format int16_t raw_value = voltage * 1000.0; //format
return _wireWriteRegister(&dev->i2c_dev,INA3221_REG_VALID_POWER_UPPER_LIMIT, *(uint16_t*)&raw_value); return _wireWriteRegister(&dev->i2c_dev, INA3221_REG_VALID_POWER_UPPER_LIMIT, *(uint16_t*)&raw_value);
} }
int ina3221_setPowerValidLowerLimit(ina3221_t *dev, float voltage) int ina3221_setPowerValidLowerLimit(ina3221_t *dev, float voltage)
{ {
if(!dev->config.ebus) if (!dev->config.ebus)
{ {
debug("Bus not enable. Dev:%u:%X\n", dev->bus, dev->addr); debug("Bus not enable. Dev:%u:%X\n", dev->bus, dev->addr);
return -ENOTSUP; return -ENOTSUP;
} }
int16_t raw_value = voltage*1000.0; // round and format int16_t raw_value = voltage * 1000.0; // round and format
return _wireWriteRegister(&dev->i2c_dev,INA3221_REG_VALID_POWER_LOWER_LIMIT, *(uint16_t*)&raw_value); return _wireWriteRegister(&dev->i2c_dev, INA3221_REG_VALID_POWER_LOWER_LIMIT, *(uint16_t*)&raw_value);
} }

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

@ -11,12 +11,12 @@
#define CMD_EEPROM 0x60 #define CMD_EEPROM 0x60
#define BIT_READY 0x80 #define BIT_READY 0x80
static void read_data(i2c_dev_t* dev, uint8_t *buf, uint8_t size) static void read_data(i2c_dev_t *dev, uint8_t *buf, uint8_t size)
{ {
i2c_slave_read(dev->bus, dev->addr , NULL, buf, size); i2c_slave_read(dev->bus, dev->addr, NULL, buf, size);
} }
bool mcp4725_eeprom_busy(i2c_dev_t* dev) bool mcp4725_eeprom_busy(i2c_dev_t *dev)
{ {
uint8_t res; uint8_t res;
read_data(dev, &res, 1); read_data(dev, &res, 1);
@ -24,7 +24,7 @@ bool mcp4725_eeprom_busy(i2c_dev_t* dev)
return !(res & BIT_READY); return !(res & BIT_READY);
} }
mcp4725_power_mode_t mcp4725_get_power_mode(i2c_dev_t* dev, bool eeprom) mcp4725_power_mode_t mcp4725_get_power_mode(i2c_dev_t *dev, bool eeprom)
{ {
uint8_t buf[4]; uint8_t buf[4];
read_data(dev, buf, eeprom ? 4 : 1); read_data(dev, buf, eeprom ? 4 : 1);
@ -32,7 +32,7 @@ mcp4725_power_mode_t mcp4725_get_power_mode(i2c_dev_t* dev, bool eeprom)
return (eeprom ? buf[3] >> 5 : buf[0] >> 1) & 0x03; return (eeprom ? buf[3] >> 5 : buf[0] >> 1) & 0x03;
} }
void mcp4725_set_power_mode(i2c_dev_t* dev, mcp4725_power_mode_t mode, bool eeprom) void mcp4725_set_power_mode(i2c_dev_t *dev, mcp4725_power_mode_t mode, bool eeprom)
{ {
uint16_t value = mcp4725_get_raw_output(dev, eeprom); uint16_t value = mcp4725_get_raw_output(dev, eeprom);
uint8_t data[] = { uint8_t data[] = {
@ -43,7 +43,7 @@ void mcp4725_set_power_mode(i2c_dev_t* dev, mcp4725_power_mode_t mode, bool eepr
i2c_slave_write(dev->bus, dev->addr, &data[0], &data[1], 2); i2c_slave_write(dev->bus, dev->addr, &data[0], &data[1], 2);
} }
uint16_t mcp4725_get_raw_output(i2c_dev_t* dev, bool eeprom) uint16_t mcp4725_get_raw_output(i2c_dev_t *dev, bool eeprom)
{ {
uint8_t buf[5]; uint8_t buf[5];
read_data(dev, buf, eeprom ? 5 : 3); read_data(dev, buf, eeprom ? 5 : 3);
@ -53,7 +53,7 @@ uint16_t mcp4725_get_raw_output(i2c_dev_t* dev, bool eeprom)
: ((uint16_t)buf[0] << 4) | (buf[1] >> 4); : ((uint16_t)buf[0] << 4) | (buf[1] >> 4);
} }
void mcp4725_set_raw_output(i2c_dev_t* dev, uint16_t value, bool eeprom) void mcp4725_set_raw_output(i2c_dev_t *dev, uint16_t value, bool eeprom)
{ {
uint8_t data[] = { uint8_t data[] = {
(eeprom ? CMD_EEPROM : CMD_DAC), (eeprom ? CMD_EEPROM : CMD_DAC),

View file

@ -42,7 +42,7 @@ typedef enum
* @param addr Device address * @param addr Device address
* @return true when EEPROM is busy * @return true when EEPROM is busy
*/ */
bool mcp4725_eeprom_busy(i2c_dev_t* dev); bool mcp4725_eeprom_busy(i2c_dev_t *dev);
/** /**
* Get power mode * Get power mode
@ -50,7 +50,7 @@ bool mcp4725_eeprom_busy(i2c_dev_t* dev);
* @param eeprom Read power mode from EEPROM if true * @param eeprom Read power mode from EEPROM if true
* @return Power mode * @return Power mode
*/ */
mcp4725_power_mode_t mcp4725_get_power_mode(i2c_dev_t* dev, bool eeprom); mcp4725_power_mode_t mcp4725_get_power_mode(i2c_dev_t *dev, bool eeprom);
/** /**
* Set power mode * Set power mode
@ -58,7 +58,7 @@ mcp4725_power_mode_t mcp4725_get_power_mode(i2c_dev_t* dev, bool eeprom);
* @param mode Power mode * @param mode Power mode
* @param eeprom Store mode to device EEPROM if true * @param eeprom Store mode to device EEPROM if true
*/ */
void mcp4725_set_power_mode(i2c_dev_t* dev, mcp4725_power_mode_t mode, bool eeprom); void mcp4725_set_power_mode(i2c_dev_t *dev, mcp4725_power_mode_t mode, bool eeprom);
/** /**
* Get current DAC value * Get current DAC value
@ -66,7 +66,7 @@ void mcp4725_set_power_mode(i2c_dev_t* dev, mcp4725_power_mode_t mode, bool eepr
* @param eeprom Read value from device EEPROM if true * @param eeprom Read value from device EEPROM if true
* @return Raw output value, 0..4095 * @return Raw output value, 0..4095
*/ */
uint16_t mcp4725_get_raw_output(i2c_dev_t* dev, bool eeprom); uint16_t mcp4725_get_raw_output(i2c_dev_t *dev, bool eeprom);
/** /**
* Set DAC output value * Set DAC output value
@ -74,7 +74,7 @@ uint16_t mcp4725_get_raw_output(i2c_dev_t* dev, bool eeprom);
* @param value Raw output value, 0..4095 * @param value Raw output value, 0..4095
* @param eeprom Store value to device EEPROM if true * @param eeprom Store value to device EEPROM if true
*/ */
void mcp4725_set_raw_output(i2c_dev_t* dev, uint16_t value, bool eeprom); void mcp4725_set_raw_output(i2c_dev_t *dev, uint16_t value, bool eeprom);
/** /**
* Get current DAC output voltage * Get current DAC output voltage
@ -83,7 +83,7 @@ void mcp4725_set_raw_output(i2c_dev_t* dev, uint16_t value, bool eeprom);
* @param eeprom Read voltage from device EEPROM if true * @param eeprom Read voltage from device EEPROM if true
* @return Current output voltage, volts * @return Current output voltage, volts
*/ */
inline float mcp4725_get_voltage(i2c_dev_t* dev, float vdd, bool eeprom) inline float mcp4725_get_voltage(i2c_dev_t *dev, float vdd, bool eeprom)
{ {
return vdd / MCP4725_MAX_VALUE * mcp4725_get_raw_output(dev, eeprom); return vdd / MCP4725_MAX_VALUE * mcp4725_get_raw_output(dev, eeprom);
} }
@ -95,7 +95,7 @@ inline float mcp4725_get_voltage(i2c_dev_t* dev, float vdd, bool eeprom)
* @param value Output value, volts * @param value Output value, volts
* @param eeprom Store value to device EEPROM if true * @param eeprom Store value to device EEPROM if true
*/ */
inline void mcp4725_set_voltage(i2c_dev_t* dev, float vdd, float value, bool eeprom) inline void mcp4725_set_voltage(i2c_dev_t *dev, float vdd, float value, bool eeprom)
{ {
mcp4725_set_raw_output(dev, MCP4725_MAX_VALUE / vdd * value, eeprom); mcp4725_set_raw_output(dev, MCP4725_MAX_VALUE / vdd * value, eeprom);
} }

View file

@ -25,7 +25,7 @@
*/ */
#define CONVERSION_TIME 20 / portTICK_PERIOD_MS // milliseconds #define CONVERSION_TIME 20 / portTICK_PERIOD_MS // milliseconds
static inline int reset(i2c_dev_t* i2c_dev) static inline int reset(i2c_dev_t *i2c_dev)
{ {
uint8_t buf[1] = { RESET }; uint8_t buf[1] = { RESET };
return i2c_slave_write(i2c_dev->bus, i2c_dev->addr, NULL, buf, 1); return i2c_slave_write(i2c_dev->bus, i2c_dev->addr, NULL, buf, 1);
@ -34,33 +34,33 @@ static inline int reset(i2c_dev_t* i2c_dev)
static inline bool read_prom(ms561101ba03_t *dev) static inline bool read_prom(ms561101ba03_t *dev)
{ {
uint8_t tmp[2] = { 0, 0 }; uint8_t tmp[2] = { 0, 0 };
uint8_t reg = 0xA2 ; uint8_t reg = 0xA2;
if (i2c_slave_read(dev->i2c_dev.bus, dev->i2c_dev.addr, &reg, tmp, 2)) if (i2c_slave_read(dev->i2c_dev.bus, dev->i2c_dev.addr, &reg, tmp, 2))
return false; return false;
dev->config_data.sens = tmp[0] << 8 | tmp[1]; dev->config_data.sens = tmp[0] << 8 | tmp[1];
reg = 0xA4 ; reg = 0xA4;
if (i2c_slave_read(dev->i2c_dev.bus, dev->i2c_dev.addr, &reg, tmp, 2)) if (i2c_slave_read(dev->i2c_dev.bus, dev->i2c_dev.addr, &reg, tmp, 2))
return false; return false;
dev->config_data.off = tmp[0] << 8 | tmp[1]; dev->config_data.off = tmp[0] << 8 | tmp[1];
reg = 0xA6 ; reg = 0xA6;
if (i2c_slave_read(dev->i2c_dev.bus, dev->i2c_dev.addr, &reg, tmp, 2)) if (i2c_slave_read(dev->i2c_dev.bus, dev->i2c_dev.addr, &reg, tmp, 2))
return false; return false;
dev->config_data.tcs = tmp[0] << 8 | tmp[1]; dev->config_data.tcs = tmp[0] << 8 | tmp[1];
reg = 0xA8 ; reg = 0xA8;
if (i2c_slave_read(dev->i2c_dev.bus, dev->i2c_dev.addr, &reg, tmp, 2)) if (i2c_slave_read(dev->i2c_dev.bus, dev->i2c_dev.addr, &reg, tmp, 2))
return false; return false;
dev->config_data.tco = tmp[0] << 8 | tmp[1]; dev->config_data.tco = tmp[0] << 8 | tmp[1];
reg = 0xAA ; reg = 0xAA;
if (i2c_slave_read(dev->i2c_dev.bus, dev->i2c_dev.addr, &reg, tmp, 2)) if (i2c_slave_read(dev->i2c_dev.bus, dev->i2c_dev.addr, &reg, tmp, 2))
return false; return false;
dev->config_data.t_ref = tmp[0] << 8 | tmp[1]; dev->config_data.t_ref = tmp[0] << 8 | tmp[1];
reg = 0xAC ; reg = 0xAC;
if (i2c_slave_read(dev->i2c_dev.bus, dev->i2c_dev.addr, &reg, tmp, 2)) if (i2c_slave_read(dev->i2c_dev.bus, dev->i2c_dev.addr, &reg, tmp, 2))
return false; return false;
dev->config_data.tempsens = tmp[0] << 8 | tmp[1]; dev->config_data.tempsens = tmp[0] << 8 | tmp[1];
@ -80,11 +80,11 @@ static inline int start_temperature_conversion(ms561101ba03_t *dev) //D2
return i2c_slave_write(dev->i2c_dev.bus, dev->i2c_dev.addr, NULL, &buf, 1); return i2c_slave_write(dev->i2c_dev.bus, dev->i2c_dev.addr, NULL, &buf, 1);
} }
static inline bool read_adc(i2c_dev_t* i2c_dev, uint32_t *result) static inline bool read_adc(i2c_dev_t *i2c_dev, uint32_t *result)
{ {
*result = 0; *result = 0;
uint8_t tmp[3]; uint8_t tmp[3];
uint8_t reg = 0x00 ; uint8_t reg = 0x00;
if (i2c_slave_read(i2c_dev->bus, i2c_dev->addr, &reg, tmp, 3)) if (i2c_slave_read(i2c_dev->bus, i2c_dev->addr, &reg, tmp, 3))
return false; return false;

View file

@ -61,7 +61,7 @@ typedef struct
*/ */
typedef struct typedef struct
{ {
i2c_dev_t i2c_dev; //!< I2C device settings i2c_dev_t i2c_dev; //!< I2C device settings
ms561101ba03_osr_t osr; //!< Oversampling setting ms561101ba03_osr_t osr; //!< Oversampling setting
ms561101ba03_config_data_t config_data; //!< Device configuration, filled upon initalize ms561101ba03_config_data_t config_data; //!< Device configuration, filled upon initalize
ms561101ba03_result_t result; //!< Result, filled upon co ms561101ba03_result_t result; //!< Result, filled upon co

View file

@ -108,7 +108,7 @@ bool onewire_write(int pin, uint8_t v) {
bool onewire_write_bytes(int pin, const uint8_t *buf, size_t count) { bool onewire_write_bytes(int pin, const uint8_t *buf, size_t count) {
size_t i; size_t i;
for (i = 0 ; i < count ; i++) { for (i = 0; i < count; i++) {
if (!onewire_write(pin, buf[i])) { if (!onewire_write(pin, buf[i])) {
return false; return false;
} }
@ -138,7 +138,7 @@ bool onewire_read_bytes(int pin, uint8_t *buf, size_t count) {
size_t i; size_t i;
int b; int b;
for (i = 0 ; i < count ; i++) { for (i = 0; i < count; i++) {
b = onewire_read(pin); b = onewire_read(pin);
if (b < 0) return false; if (b < 0) return false;
buf[i] = b; buf[i] = b;
@ -434,7 +434,7 @@ uint16_t onewire_crc16(const uint8_t* input, size_t len, uint16_t crc_iv) {
{ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 }; { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 };
uint16_t i; uint16_t i;
for (i = 0 ; i < len ; i++) { for (i = 0; i < len; i++) {
// Even though we're just copying a byte from the input, // Even though we're just copying a byte from the input,
// we'll be doing 16-bit computation with it. // we'll be doing 16-bit computation with it.
uint16_t cdata = input[i]; uint16_t cdata = input[i];

View file

@ -58,13 +58,13 @@ inline static uint32_t round_div(uint32_t x, uint32_t y)
return (x + y / 2) / y; return (x + y / 2) / y;
} }
inline static void write_reg(i2c_dev_t* dev, uint8_t reg, uint8_t val) inline static void write_reg(i2c_dev_t *dev, uint8_t reg, uint8_t val)
{ {
if (i2c_slave_write(dev->bus, dev->addr, &reg, &val, 1)) if (i2c_slave_write(dev->bus, dev->addr, &reg, &val, 1))
debug("Could not write 0x%02x to 0x%02x, bus %u, addr = 0x%02x", reg, val, dev->bus, dev->addr); debug("Could not write 0x%02x to 0x%02x, bus %u, addr = 0x%02x", reg, val, dev->bus, dev->addr);
} }
inline static uint8_t read_reg(i2c_dev_t* dev, uint8_t reg) inline static uint8_t read_reg(i2c_dev_t *dev, uint8_t reg)
{ {
uint8_t res = 0; uint8_t res = 0;
if (i2c_slave_read(dev->bus, dev->addr, &reg, &res, 1)) if (i2c_slave_read(dev->bus, dev->addr, &reg, &res, 1))
@ -72,18 +72,18 @@ inline static uint8_t read_reg(i2c_dev_t* dev, uint8_t reg)
return res; return res;
} }
inline static void update_reg(i2c_dev_t* dev, uint8_t reg, uint8_t mask, uint8_t val) inline static void update_reg(i2c_dev_t *dev, uint8_t reg, uint8_t mask, uint8_t val)
{ {
write_reg(dev, reg, (read_reg(dev, reg) & ~mask) | val); write_reg(dev, reg, (read_reg(dev, reg) & ~mask) | val);
} }
void pca9685_init(i2c_dev_t* dev) void pca9685_init(i2c_dev_t *dev)
{ {
// Enable autoincrement // Enable autoincrement
update_reg(dev, REG_MODE1, MODE1_AI, MODE1_AI); update_reg(dev, REG_MODE1, MODE1_AI, MODE1_AI);
} }
bool pca9685_set_subaddr(i2c_dev_t* dev, uint8_t num, uint8_t subaddr, bool enable) bool pca9685_set_subaddr(i2c_dev_t *dev, uint8_t num, uint8_t subaddr, bool enable)
{ {
if (num > MAX_SUBADDR) if (num > MAX_SUBADDR)
{ {
@ -99,19 +99,19 @@ bool pca9685_set_subaddr(i2c_dev_t* dev, uint8_t num, uint8_t subaddr, bool enab
return true; return true;
} }
bool pca9685_is_sleeping(i2c_dev_t* dev) bool pca9685_is_sleeping(i2c_dev_t *dev)
{ {
return (read_reg(dev, REG_MODE1) & MODE1_SLEEP) != 0; return (read_reg(dev, REG_MODE1) & MODE1_SLEEP) != 0;
} }
void pca9685_sleep(i2c_dev_t* dev, bool sleep) void pca9685_sleep(i2c_dev_t *dev, bool sleep)
{ {
update_reg(dev, REG_MODE1, MODE1_SLEEP, sleep ? MODE1_SLEEP : 0); update_reg(dev, REG_MODE1, MODE1_SLEEP, sleep ? MODE1_SLEEP : 0);
if (!sleep) if (!sleep)
sdk_os_delay_us(WAKEUP_DELAY_US); sdk_os_delay_us(WAKEUP_DELAY_US);
} }
void pca9685_restart(i2c_dev_t* dev) void pca9685_restart(i2c_dev_t *dev)
{ {
uint8_t mode = read_reg(dev, REG_MODE1); uint8_t mode = read_reg(dev, REG_MODE1);
if (mode & MODE1_RESTART) if (mode & MODE1_RESTART)
@ -122,32 +122,32 @@ void pca9685_restart(i2c_dev_t* dev)
write_reg(dev, REG_MODE1, (mode & ~MODE1_SLEEP) | MODE1_RESTART); write_reg(dev, REG_MODE1, (mode & ~MODE1_SLEEP) | MODE1_RESTART);
} }
bool pca9685_is_output_inverted(i2c_dev_t* dev) bool pca9685_is_output_inverted(i2c_dev_t *dev)
{ {
return (read_reg(dev, REG_MODE2) & MODE2_INVRT) != 0; return (read_reg(dev, REG_MODE2) & MODE2_INVRT) != 0;
} }
void pca9685_set_output_inverted(i2c_dev_t* dev, bool inverted) void pca9685_set_output_inverted(i2c_dev_t *dev, bool inverted)
{ {
update_reg(dev, REG_MODE2, MODE2_INVRT, inverted ? MODE2_INVRT : 0); update_reg(dev, REG_MODE2, MODE2_INVRT, inverted ? MODE2_INVRT : 0);
} }
bool pca9685_get_output_open_drain(i2c_dev_t* dev) bool pca9685_get_output_open_drain(i2c_dev_t *dev)
{ {
return (read_reg(dev, REG_MODE2) & MODE2_OUTDRV) == 0; return (read_reg(dev, REG_MODE2) & MODE2_OUTDRV) == 0;
} }
void pca9685_set_output_open_drain(i2c_dev_t* dev, bool open_drain) void pca9685_set_output_open_drain(i2c_dev_t *dev, bool open_drain)
{ {
update_reg(dev, REG_MODE2, MODE2_OUTDRV, open_drain ? 0 : MODE2_OUTDRV); update_reg(dev, REG_MODE2, MODE2_OUTDRV, open_drain ? 0 : MODE2_OUTDRV);
} }
uint8_t pca9685_get_prescaler(i2c_dev_t* dev) uint8_t pca9685_get_prescaler(i2c_dev_t *dev)
{ {
return read_reg(dev, REG_PRE_SCALE); return read_reg(dev, REG_PRE_SCALE);
} }
bool pca9685_set_prescaler(i2c_dev_t* dev, uint8_t prescaler) bool pca9685_set_prescaler(i2c_dev_t *dev, uint8_t prescaler)
{ {
if (prescaler < MIN_PRESCALER) if (prescaler < MIN_PRESCALER)
{ {
@ -161,12 +161,12 @@ bool pca9685_set_prescaler(i2c_dev_t* dev, uint8_t prescaler)
return true; return true;
} }
uint16_t pca9685_get_pwm_frequency(i2c_dev_t* dev) uint16_t pca9685_get_pwm_frequency(i2c_dev_t *dev)
{ {
return INTERNAL_FREQ / ((uint32_t)4096 * (read_reg(dev, REG_PRE_SCALE) + 1)); return INTERNAL_FREQ / ((uint32_t)4096 * (read_reg(dev, REG_PRE_SCALE) + 1));
} }
bool pca9685_set_pwm_frequency(i2c_dev_t* dev, uint16_t freq) bool pca9685_set_pwm_frequency(i2c_dev_t *dev, uint16_t freq)
{ {
uint16_t prescaler = round_div(INTERNAL_FREQ, (uint32_t)4096 * freq) - 1; uint16_t prescaler = round_div(INTERNAL_FREQ, (uint32_t)4096 * freq) - 1;
if (prescaler < MIN_PRESCALER || prescaler > MAX_PRESCALER) if (prescaler < MIN_PRESCALER || prescaler > MAX_PRESCALER)
@ -178,7 +178,7 @@ bool pca9685_set_pwm_frequency(i2c_dev_t* dev, uint16_t freq)
return pca9685_set_prescaler(dev, prescaler); return pca9685_set_prescaler(dev, prescaler);
} }
void pca9685_set_pwm_value(i2c_dev_t* dev, uint8_t channel, uint16_t val) void pca9685_set_pwm_value(i2c_dev_t *dev, uint8_t channel, uint16_t val)
{ {
uint8_t reg = channel > MAX_CHANNEL ? REG_ALL_LED : REG_LED_N(channel); uint8_t reg = channel > MAX_CHANNEL ? REG_ALL_LED : REG_LED_N(channel);
@ -200,7 +200,7 @@ void pca9685_set_pwm_value(i2c_dev_t* dev, uint8_t channel, uint16_t val)
} }
} }
bool pca9685_set_pwm_values(i2c_dev_t* dev, uint8_t first_ch, uint8_t channels, const uint16_t *values) bool pca9685_set_pwm_values(i2c_dev_t *dev, uint8_t first_ch, uint8_t channels, const uint16_t *values)
{ {
if (channels == 0 || first_ch + channels - 1 > MAX_CHANNEL) if (channels == 0 || first_ch + channels - 1 > MAX_CHANNEL)
{ {

View file

@ -23,7 +23,7 @@ extern "C"
* Init device * Init device
* @param addr Device address * @param addr Device address
*/ */
void pca9685_init(i2c_dev_t* dev); void pca9685_init(i2c_dev_t *dev);
/** /**
* Setup device subaddress (see section 7.3.6 if the datasheet) * Setup device subaddress (see section 7.3.6 if the datasheet)
@ -33,62 +33,62 @@ void pca9685_init(i2c_dev_t* dev);
* @param enable True to enable subaddress, false to disable * @param enable True to enable subaddress, false to disable
* @return False if error occured * @return False if error occured
*/ */
bool pca9685_set_subaddr(i2c_dev_t* dev, uint8_t num, uint8_t subaddr, bool enable); bool pca9685_set_subaddr(i2c_dev_t *dev, uint8_t num, uint8_t subaddr, bool enable);
/** /**
* Restart device (see section 7.3.1.1 of the datasheet) * Restart device (see section 7.3.1.1 of the datasheet)
* @param addr Device address * @param addr Device address
*/ */
void pca9685_restart(i2c_dev_t* dev); void pca9685_restart(i2c_dev_t *dev);
/** /**
* Check if device is in sleep mode * Check if device is in sleep mode
* @param addr Device address * @param addr Device address
* @return True if device is sleeping * @return True if device is sleeping
*/ */
bool pca9685_is_sleeping(i2c_dev_t* dev); bool pca9685_is_sleeping(i2c_dev_t *dev);
/** /**
* Switch device to low-power mode or wake it up. * Switch device to low-power mode or wake it up.
* @param addr Device address * @param addr Device address
* @param sleep True for sleep mode, false for wake up * @param sleep True for sleep mode, false for wake up
*/ */
void pca9685_sleep(i2c_dev_t* dev, bool sleep); void pca9685_sleep(i2c_dev_t *dev, bool sleep);
/** /**
* Get logic inversion of the outputs * Get logic inversion of the outputs
* @param addr Device address * @param addr Device address
* @return True if outputs are inverted, false otherwise * @return True if outputs are inverted, false otherwise
*/ */
bool pca9685_is_output_inverted(i2c_dev_t* dev); bool pca9685_is_output_inverted(i2c_dev_t *dev);
/** /**
* Logically invert outputs (see section 7.7 of the datasheet) * Logically invert outputs (see section 7.7 of the datasheet)
* @param addr Device address * @param addr Device address
* @param inverted True for inverted outputs * @param inverted True for inverted outputs
*/ */
void pca9685_set_output_inverted(i2c_dev_t* dev, bool inverted); void pca9685_set_output_inverted(i2c_dev_t *dev, bool inverted);
/** /**
* Get outputs mode * Get outputs mode
* @param addr Device address * @param addr Device address
* @return True if outputs are in open drain mode * @return True if outputs are in open drain mode
*/ */
bool pca9685_get_output_open_drain(i2c_dev_t* dev); bool pca9685_get_output_open_drain(i2c_dev_t *dev);
/** /**
* Set outputs mode * Set outputs mode
* @param addr Device address * @param addr Device address
* @param open_drain True to set open drain mode, false to normal mode * @param open_drain True to set open drain mode, false to normal mode
*/ */
void pca9685_set_output_open_drain(i2c_dev_t* dev, bool open_drain); void pca9685_set_output_open_drain(i2c_dev_t *dev, bool open_drain);
/** /**
* Get current PWM frequency prescaler. * Get current PWM frequency prescaler.
* @param addr Device address * @param addr Device address
* @return Frequency prescaler * @return Frequency prescaler
*/ */
uint8_t pca9685_get_prescaler(i2c_dev_t* dev); uint8_t pca9685_get_prescaler(i2c_dev_t *dev);
/** /**
* Set PWM frequency prescaler. * Set PWM frequency prescaler.
@ -96,14 +96,14 @@ uint8_t pca9685_get_prescaler(i2c_dev_t* dev);
* @param prescaler Prescaler value * @param prescaler Prescaler value
* @return False if error occured * @return False if error occured
*/ */
bool pca9685_set_prescaler(i2c_dev_t* dev, uint8_t prescaler); bool pca9685_set_prescaler(i2c_dev_t *dev, uint8_t prescaler);
/** /**
* Get current PWM frequency * Get current PWM frequency
* @param addr Device address * @param addr Device address
* @return PWM frequency, Hz * @return PWM frequency, Hz
*/ */
uint16_t pca9685_get_pwm_frequency(i2c_dev_t* dev); uint16_t pca9685_get_pwm_frequency(i2c_dev_t *dev);
/** /**
* Set PWM frequency * Set PWM frequency
@ -111,7 +111,7 @@ uint16_t pca9685_get_pwm_frequency(i2c_dev_t* dev);
* @param freq PWM frequency, Hz * @param freq PWM frequency, Hz
* @return False if error occured * @return False if error occured
*/ */
bool pca9685_set_pwm_frequency(i2c_dev_t* dev, uint16_t freq); bool pca9685_set_pwm_frequency(i2c_dev_t *dev, uint16_t freq);
/** /**
* Set PWM value on output channel * Set PWM value on output channel
@ -119,7 +119,7 @@ bool pca9685_set_pwm_frequency(i2c_dev_t* dev, uint16_t freq);
* @param channel Channel number, 0..15 or >15 for all channels * @param channel Channel number, 0..15 or >15 for all channels
* @param val PWM value, 0..4096 * @param val PWM value, 0..4096
*/ */
void pca9685_set_pwm_value(i2c_dev_t* dev, uint8_t channel, uint16_t val); void pca9685_set_pwm_value(i2c_dev_t *dev, uint8_t channel, uint16_t val);
/** /**
* Set PWM values on output channels * Set PWM values on output channels
@ -129,7 +129,7 @@ void pca9685_set_pwm_value(i2c_dev_t* dev, uint8_t channel, uint16_t val);
* @param values Array of the channel values, each 0..4096 * @param values Array of the channel values, each 0..4096
* @return False if error occured * @return False if error occured
*/ */
bool pca9685_set_pwm_values(i2c_dev_t* dev, uint8_t first_ch, uint8_t channels, const uint16_t *values); bool pca9685_set_pwm_values(i2c_dev_t *dev, uint8_t first_ch, uint8_t channels, const uint16_t *values);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -1,14 +1,14 @@
#include "pcf8574.h" #include "pcf8574.h"
uint8_t pcf8574_port_read(i2c_dev_t* dev) uint8_t pcf8574_port_read(i2c_dev_t *dev)
{ {
uint8_t res; uint8_t res;
if (i2c_slave_read(dev->bus, dev->addr, NULL, &res, 1)) if (i2c_slave_read(dev->bus, dev->addr, NULL, &res, 1))
return 0; return 0;
return res; return res;
} }
size_t pcf8574_port_read_buf(i2c_dev_t* dev, void *buf, size_t len) size_t pcf8574_port_read_buf(i2c_dev_t *dev, void *buf, size_t len)
{ {
if (!len || !buf) return 0; if (!len || !buf) return 0;
uint8_t *_buf = (uint8_t *)buf; uint8_t *_buf = (uint8_t *)buf;
@ -18,7 +18,7 @@ size_t pcf8574_port_read_buf(i2c_dev_t* dev, void *buf, size_t len)
return len; return len;
} }
size_t pcf8574_port_write_buf(const i2c_dev_t* dev, void *buf, size_t len) size_t pcf8574_port_write_buf(const i2c_dev_t *dev, void *buf, size_t len)
{ {
if (!len || !buf) return 0; if (!len || !buf) return 0;
uint8_t *_buf = (uint8_t *)buf; uint8_t *_buf = (uint8_t *)buf;
@ -28,19 +28,19 @@ size_t pcf8574_port_write_buf(const i2c_dev_t* dev, void *buf, size_t len)
return len; return len;
} }
void pcf8574_port_write(const i2c_dev_t* dev, uint8_t value) void pcf8574_port_write(const i2c_dev_t *dev, uint8_t value)
{ {
i2c_slave_write(dev->bus, dev->addr, NULL, &value, 1); i2c_slave_write(dev->bus, dev->addr, NULL, &value, 1);
} }
bool pcf8574_gpio_read(i2c_dev_t* dev, uint8_t num) bool pcf8574_gpio_read(i2c_dev_t *dev, uint8_t num)
{ {
return (bool)((pcf8574_port_read(dev) >> num) & 1); return (bool)((pcf8574_port_read(dev) >> num) & 1);
} }
void pcf8574_gpio_write(i2c_dev_t* dev, uint8_t num, bool value) void pcf8574_gpio_write(i2c_dev_t *dev, uint8_t num, bool value)
{ {
uint8_t bit = (uint8_t)value << num; uint8_t bit = (uint8_t)value << num;
uint8_t mask = ~(1 << num); uint8_t mask = ~(1 << num);
pcf8574_port_write (dev, (pcf8574_port_read(dev) & mask) | bit); pcf8574_port_write(dev, (pcf8574_port_read(dev) & mask) | bit);
} }

View file

@ -20,7 +20,7 @@ extern "C"
* \param addr I2C register address (0b0100<A2><A1><A0> for PCF8574) * \param addr I2C register address (0b0100<A2><A1><A0> for PCF8574)
* \return 8-bit GPIO port value * \return 8-bit GPIO port value
*/ */
uint8_t pcf8574_port_read(i2c_dev_t* dev); uint8_t pcf8574_port_read(i2c_dev_t *dev);
/** /**
* \brief Continiously read GPIO port values to buffer * \brief Continiously read GPIO port values to buffer
@ -29,14 +29,14 @@ uint8_t pcf8574_port_read(i2c_dev_t* dev);
* @param len Buffer length * @param len Buffer length
* @return Number of bytes read * @return Number of bytes read
*/ */
size_t pcf8574_port_read_buf(i2c_dev_t* dev, void *buf, size_t len); size_t pcf8574_port_read_buf(i2c_dev_t *dev, void *buf, size_t len);
/** /**
* \brief Write value to GPIO port * \brief Write value to GPIO port
* \param addr I2C register address (0b0100<A2><A1><A0> for PCF8574) * \param addr I2C register address (0b0100<A2><A1><A0> for PCF8574)
* \param value GPIO port value * \param value GPIO port value
*/ */
void pcf8574_port_write(const i2c_dev_t* dev, uint8_t value); void pcf8574_port_write(const i2c_dev_t *dev, uint8_t value);
/** /**
* \brief Continiously write GPIO values to GPIO port * \brief Continiously write GPIO values to GPIO port
@ -45,7 +45,7 @@ void pcf8574_port_write(const i2c_dev_t* dev, uint8_t value);
* @param len Buffer length * @param len Buffer length
* @return Number of bytes written * @return Number of bytes written
*/ */
size_t pcf8574_port_write_buf(const i2c_dev_t* dev, void *buf, size_t len); size_t pcf8574_port_write_buf(const i2c_dev_t *dev, void *buf, size_t len);
/** /**
* \brief Read input value of a GPIO pin * \brief Read input value of a GPIO pin
@ -53,7 +53,7 @@ size_t pcf8574_port_write_buf(const i2c_dev_t* dev, void *buf, size_t len);
* \param num pin number (0..7) * \param num pin number (0..7)
* \return GPIO pin value * \return GPIO pin value
*/ */
bool pcf8574_gpio_read(i2c_dev_t* dev, uint8_t num); bool pcf8574_gpio_read(i2c_dev_t *dev, uint8_t num);
/** /**
* \brief Set GPIO pin output * \brief Set GPIO pin output
@ -63,7 +63,7 @@ bool pcf8574_gpio_read(i2c_dev_t* dev, uint8_t num);
* \param num pin number (0..7) * \param num pin number (0..7)
* \param value true for high level * \param value true for high level
*/ */
void pcf8574_gpio_write(i2c_dev_t* dev, uint8_t num, bool value); void pcf8574_gpio_write(i2c_dev_t *dev, uint8_t num, bool value);
#ifdef __cplusplus #ifdef __cplusplus
} }

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,
.width = 128, .screen = SSD1306_SCREEN, // or SH1106_SCREEN
.height = 64 .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)) { 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,10 +69,35 @@ 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,
.cs_pin = CS_PIN, .screen = SSD1306_SCREEN,
.dc_pin = DC_PIN, .cs_pin = CS_PIN,
.width = 128, .dc_pin = DC_PIN,
.height = 64 .width = 128,
.height = 64
};
...
if (ssd1306_init(&device)) {
// An error occured, while performing SSD1306 init
}
// 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
}; };
... ...

View file

@ -85,11 +85,10 @@
#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)
{ {
return i2c_slave_write(dev->i2c_dev.bus, dev->i2c_dev.addr , &reg, data, len); return i2c_slave_write(dev->i2c_dev.bus, dev->i2c_dev.addr, &reg, data, len);
} }
#endif #endif
@ -120,7 +119,7 @@ int ssd1306_command(const ssd1306_t *dev, uint8_t cmd)
#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);
spi_set_command(SPI_BUS,1,0); // command mode spi_set_command(SPI_BUS, 1, 0); // command mode
spi_transfer_8(SPI_BUS, cmd); spi_transfer_8(SPI_BUS, cmd);
spi_clear_command(SPI_BUS); spi_clear_command(SPI_BUS);
gpio_write(dev->cs_pin, true); gpio_write(dev->cs_pin, true);
@ -135,7 +134,7 @@ int ssd1306_command(const ssd1306_t *dev, uint8_t cmd)
} }
/* Perform default init routine according /* Perform default init routine according
* to SSD1306 datasheet from adafruit.com */ * to SSD1306 datasheet from adafruit.com */
int ssd1306_init(const ssd1306_t *dev) int ssd1306_init(const ssd1306_t *dev)
{ {
uint8_t pin_cfg; uint8_t pin_cfg;
@ -221,10 +220,12 @@ 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
return err; return err;
if ((err = ssd1306_command(dev, SH1106_SET_LOW_COL_ADDR | (x & 0xf)))) // Set lower column address if ((err = ssd1306_command(dev, SH1106_SET_LOW_COL_ADDR | (x & 0xf)))) // Set lower column address
@ -237,11 +238,10 @@ int ssd1306_load_frame_buffer(const ssd1306_t *dev, uint8_t buf[])
uint16_t i; uint16_t i;
uint8_t j; uint8_t j;
#if (SSD1306_I2C_SUPPORT) #if (SSD1306_I2C_SUPPORT)
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,35 +249,33 @@ 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;
} }
break; break;
#endif #endif
#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
gpio_write(dev->cs_pin, false); gpio_write(dev->cs_pin, false);
if (buf) if (buf)
spi_transfer(SPI_BUS, &buf[dev->width*i], NULL, dev->width, SPI_8BIT); spi_transfer(SPI_BUS, &buf[dev->width * i], NULL, dev->width, SPI_8BIT);
else else
spi_repeat_send_8(SPI_BUS,0,dev->width); spi_repeat_send_8(SPI_BUS, 0, dev->width);
} }
} }
gpio_write(dev->cs_pin, true); gpio_write(dev->cs_pin, true);
@ -286,36 +284,30 @@ 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
gpio_write(dev->cs_pin, false); gpio_write(dev->cs_pin, false);
if (buf) if (buf)
for (j = 0 ; j < dev->width ; j++) for (j = 0; j < dev->width; j++)
spi_transfer_8(SPI_BUS, buf[dev->width*i+j]); spi_transfer_8(SPI_BUS, buf[dev->width * i + j]);
else else
for (j = 0 ; j < dev->width ; j++) for (j = 0; j < dev->width; j++)
spi_transfer_8(SPI_BUS, buf[dev->width*i+j]); spi_transfer_8(SPI_BUS, buf[dev->width * i + j]);
} }
} }
spi_clear_command(SPI_BUS); spi_clear_command(SPI_BUS);
@ -357,41 +349,38 @@ 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;
switch (dev->screen) { switch (dev->screen) {
case SH1106_SCREEN: case SH1106_SCREEN:
if ((err = ssd1306_command(dev, SH1106_SET_CHARGE_PUMP))) if ((err = ssd1306_command(dev, SH1106_SET_CHARGE_PUMP)))
return err; return err;
return ssd1306_command(dev, enabled ? SH1106_CHARGE_PUMP_EN : SH1106_CHARGE_PUMP_DIS); return ssd1306_command(dev, enabled ? SH1106_CHARGE_PUMP_EN : SH1106_CHARGE_PUMP_DIS);
break; break;
case SSD1306_SCREEN: case SSD1306_SCREEN:
if ((err = ssd1306_command(dev, SSD1306_SET_CHARGE_PUMP))) if ((err = ssd1306_command(dev, SSD1306_SET_CHARGE_PUMP)))
return err; return err;
return ssd1306_command(dev, enabled ? SSD1306_CHARGE_PUMP_EN : SSD1306_CHARGE_PUMP_DIS); return ssd1306_command(dev, enabled ? SSD1306_CHARGE_PUMP_EN : SSD1306_CHARGE_PUMP_DIS);
break; break;
default: default:
debug("Unsupported screen type"); debug("Unsupported screen type");
return -ENOTSUP; return -ENOTSUP;
} }
} }
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;
} }
int err = 0; int err = 0;
if ((err = ssd1306_command(dev, SSD1306_SET_MEM_ADDR_MODE))) if ((err = ssd1306_command(dev, SSD1306_SET_MEM_ADDR_MODE)))
@ -498,7 +487,7 @@ int ssd1306_set_deseltct_lvl(const ssd1306_t *dev, uint8_t lvl)
int ssd1306_set_whole_display_lighting(const ssd1306_t *dev, bool light) int ssd1306_set_whole_display_lighting(const ssd1306_t *dev, bool light)
{ {
return ssd1306_command(dev, light ? SSD1306_SET_ENTIRE_DISP_ON : SSD1306_SET_ENTIRE_DISP_OFF); return ssd1306_command(dev, light ? SSD1306_SET_ENTIRE_DISP_ON : SSD1306_SET_ENTIRE_DISP_OFF);
} }
/* one byte of xbm - 8 dots in line of picture source /* one byte of xbm - 8 dots in line of picture source
@ -510,9 +499,9 @@ int ssd1306_load_xbm(const ssd1306_t *dev, uint8_t *xbm, uint8_t *fb)
int row = 0; int row = 0;
int column = 0; int column = 0;
for (row = 0; row < dev->height; row ++) { for (row = 0; row < dev->height; row++) {
for (column = 0; column < dev->width / 8; column++) { for (column = 0; column < dev->width / 8; column++) {
uint16_t xbm_offset = row * 16 + column; uint16_t xbm_offset = row * 16 + column;
for (bit = 0; bit < 8; bit++) { for (bit = 0; bit < 8; bit++) {
if (*(xbm + xbm_offset) & 1 << bit) { if (*(xbm + xbm_offset) & 1 << bit) {
*(fb + dev->width * (row / 8) + column * 8 + bit) |= 1 << row % 8; *(fb + dev->width * (row / 8) + column * 8 + bit) |= 1 << row % 8;
@ -532,19 +521,18 @@ 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; case OLED_COLOR_BLACK:
case OLED_COLOR_BLACK: fb[index] &= ~(1 << (y & 7));
fb[index] &= ~(1 << (y & 7)); break;
break; case OLED_COLOR_INVERT:
case OLED_COLOR_INVERT: fb[index] ^= (1 << (y & 7));
fb[index] ^= (1 << (y & 7)); break;
break; default:
default: break;
break;
} }
return 0; return 0;
} }
@ -565,32 +553,28 @@ 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;
{ ++index;
fb[index] |= mask; }
++index; break;
} case OLED_COLOR_BLACK:
break; mask = ~mask;
case OLED_COLOR_BLACK: while (t--) {
mask = ~mask; fb[index] &= mask;
while (t--) ++index;
{ }
fb[index] &= mask; break;
++index; case OLED_COLOR_INVERT:
} while (t--) {
break; fb[index] ^= mask;
case OLED_COLOR_INVERT: ++index;
while (t--) }
{ break;
fb[index] ^= mask; default:
++index; break;
}
break;
default:
break;
} }
return 0; return 0;
} }
@ -619,19 +603,18 @@ 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; case OLED_COLOR_BLACK:
case OLED_COLOR_BLACK: fb[index] &= ~mask;
fb[index] &= ~mask; break;
break; case OLED_COLOR_INVERT:
case OLED_COLOR_INVERT: fb[index] ^= mask;
fb[index] ^= mask; break;
break; default:
default: break;
break;
} }
if (t < mod) if (t < mod)
@ -640,35 +623,31 @@ int ssd1306_draw_vline(const ssd1306_t *dev, uint8_t *fb, int8_t x, int8_t y, ui
index += dev->width; index += dev->width;
} }
if (t >= 8) // byte aligned line at middle if (t >= 8) // byte aligned line at middle
{
switch (color)
{
case OLED_COLOR_WHITE:
do
{ {
fb[index] = 0xff; switch (color) {
index += dev->width; case OLED_COLOR_WHITE:
t -= 8; do {
} while (t >= 8); fb[index] = 0xff;
break; index += dev->width;
case OLED_COLOR_BLACK: t -= 8;
do } while (t >= 8);
{ break;
fb[index] = 0x00; case OLED_COLOR_BLACK:
index += dev->width; do {
t -= 8; fb[index] = 0x00;
} while (t >= 8); index += dev->width;
break; t -= 8;
case OLED_COLOR_INVERT: } while (t >= 8);
do break;
{ case OLED_COLOR_INVERT:
fb[index] = ~fb[index]; do {
index += dev->width; fb[index] = ~fb[index];
t -= 8; index += dev->width;
} while (t >= 8); t -= 8;
break; } while (t >= 8);
default: break;
break; default:
break;
} }
} }
if (t) // partial line at bottom if (t) // partial line at bottom
@ -676,19 +655,18 @@ 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; case OLED_COLOR_BLACK:
case OLED_COLOR_BLACK: fb[index] &= ~mask;
fb[index] &= ~mask; break;
break; case OLED_COLOR_INVERT:
case OLED_COLOR_INVERT: fb[index] ^= mask;
fb[index] ^= mask; break;
break; default:
default: break;
break;
} }
} }
return 0; return 0;
@ -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,15 +794,14 @@ 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)))
return err; return err;
if ((err = ssd1306_draw_hline(dev, fb, x0 - x, y0 - y, x - x1 + 1, color))) if ((err = ssd1306_draw_hline(dev, fb, x0 - x, y0 - y, x - x1 + 1, color)))
return err; return err;
if ((err = ssd1306_draw_hline(dev, fb, x0 - x, y0 + y, x - x1 + 1, color))) if ((err = ssd1306_draw_hline(dev, fb, x0 - x, y0 + y, x - x1 + 1, color)))
return err; return err;
++y; ++y;
if (radius_err < 0) { if (radius_err < 0) {
@ -845,59 +816,59 @@ 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;
if ((x1 >= dev->width) || (x1 < 0) || (y1 >= dev->height) || (y1 < 0)) if ((x1 >= dev->width) || (x1 < 0) || (y1 >= dev->height) || (y1 < 0))
return -EINVAL; return -EINVAL;
int err; int err;
bool steep = abs(y1 - y0) > abs(x1 - x0); bool steep = abs(y1 - y0) > abs(x1 - x0);
if (steep) { if (steep) {
swap(x0, y0); swap(x0, y0);
swap(x1, y1); swap(x1, y1);
} }
if (x0 > x1) { if (x0 > x1) {
swap(x0, x1); swap(x0, x1);
swap(y0, y1); swap(y0, y1);
} }
int16_t dx, dy; int16_t dx, dy;
dx = x1 - x0; dx = x1 - x0;
dy = abs(y1 - y0); dy = abs(y1 - y0);
int16_t errx = dx / 2; int16_t errx = dx / 2;
int16_t ystep; int16_t ystep;
if (y0 < y1) { if (y0 < y1) {
ystep = 1; ystep = 1;
} else { }
ystep = -1; else {
} ystep = -1;
}
for (; x0 <= x1; x0++) { for (; x0 <= x1; x0++) {
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 { }
if ((err = ssd1306_draw_pixel(dev, fb, x0, y0, color))) else {
return err; if ((err = ssd1306_draw_pixel(dev, fb, x0, y0, color)))
} return err;
errx -= dy; }
if (errx < 0) { errx -= dy;
y0 += ystep; if (errx < 0) {
errx += dx; y0 += ystep;
} errx += dx;
} }
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;
if ((err = ssd1306_draw_line(dev, fb, x0, y0, x1, y1, color))) if ((err = ssd1306_draw_line(dev, fb, x0, y0, x1, y1, color)))
@ -907,25 +878,24 @@ 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;
int err; int err;
// Sort coordinates by Y order (y2 >= y1 >= y0) // Sort coordinates by Y order (y2 >= y1 >= y0)
if (y0 > y1) { if (y0 > y1) {
swap(y0, y1); swap(x0, x1); swap(y0, y1);swap(x0, x1);
} }
if (y1 > y2) { if (y1 > y2) {
swap(y2, y1); swap(x2, x1); swap(y2, y1);swap(x2, x1);
} }
if (y0 > y1) { if (y0 > y1) {
swap(y0, y1); swap(x0, x1); swap(y0, y1);swap(x0, x1);
} }
if(y0 == y2) { // Handle awkward all-on-same-line case as its own thing if (y0 == y2) { // Handle awkward all-on-same-line case as its own thing
a = b = x0; a = b = x0;
if (x1 < a) a = x1; if (x1 < a) a = x1;
else if (x1 > b) b = x1; else if (x1 > b) b = x1;
@ -984,14 +954,13 @@ int ssd1306_fill_triangle(const ssd1306_t *dev, uint8_t *fb, int16_t x0,
*/ */
if (a > b) swap(a, b); if (a > b) swap(a, b);
if ((err = ssd1306_draw_hline(dev, fb, a, y, b - a + 1, color))) if ((err = ssd1306_draw_hline(dev, fb, a, y, b - a + 1, color)))
return err; return err;
} }
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,30 +984,29 @@ 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; case OLED_COLOR_WHITE:
case OLED_COLOR_WHITE: case OLED_COLOR_BLACK:
case OLED_COLOR_BLACK: err = ssd1306_draw_pixel(dev, fb, x + i, y + j, background);
err = ssd1306_draw_pixel(dev, fb, x + i, y + j, background); break;
break; case OLED_COLOR_INVERT:
case OLED_COLOR_INVERT: // I don't know why I need invert background
// I don't know why I need invert background 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;
int err; int err;
@ -1046,11 +1014,10 @@ 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;
++str; ++str;
if (*str) if (*str)
x += font->c; x += font->c;
@ -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;
} }
@ -1089,7 +1054,7 @@ int ssd1306_start_scroll_hori(const ssd1306_t *dev, bool way, uint8_t start, uin
return -EIO; return -EIO;
} }
int ssd1306_start_scroll_hori_vert(const ssd1306_t *dev, bool way, uint8_t start, uint8_t stop, uint8_t dy, ssd1306_scroll_t frame) int ssd1306_start_scroll_hori_vert(const ssd1306_t *dev, bool way, uint8_t start, uint8_t stop, uint8_t dy, ssd1306_scroll_t frame)
{ {
//this function dont work well if no vertical setting. //this function dont work well if no vertical setting.
if ((!dy) || (dy > 63)) if ((!dy) || (dy > 63))
@ -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

@ -65,13 +65,16 @@ typedef enum
typedef struct 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
uint8_t cs_pin ; //!< Chip Select GPIO pin, used by SSD1306_PROTO_SPI3, SSD1306_PROTO_SPI4 #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) #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
#endif #endif
@ -520,7 +523,7 @@ int ssd1306_start_scroll_hori(const ssd1306_t *dev, bool way, uint8_t start, uin
* @param frame Time interval between each scroll * @param frame Time interval between each scroll
* @return Non-zero if error occured * @return Non-zero if error occured
*/ */
int ssd1306_start_scroll_hori_vert(const ssd1306_t *dev, bool way, uint8_t start, uint8_t stop, uint8_t dy, ssd1306_scroll_t frame); int ssd1306_start_scroll_hori_vert(const ssd1306_t *dev, bool way, uint8_t start, uint8_t stop, uint8_t dy, ssd1306_scroll_t frame);
#ifdef __cplusplus #ifdef __cplusplus
extern "C" extern "C"

View file

@ -95,26 +95,33 @@
#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
static int write_register(i2c_dev_t* i2c_dev, uint8_t reg, uint8_t value) #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; reg = TSL2561_REG_COMMAND | reg;
return i2c_slave_write(i2c_dev->bus, i2c_dev->addr, &reg, &value, 1); return i2c_slave_write(i2c_dev->bus, i2c_dev->addr, &reg, &value, 1);
} }
static uint8_t read_register(i2c_dev_t* i2c_dev, uint8_t reg) static uint8_t read_register(i2c_dev_t *i2c_dev, uint8_t reg)
{ {
uint8_t data[1]; uint8_t data[1];
reg = TSL2561_REG_COMMAND | reg; reg = TSL2561_REG_COMMAND | 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];
} }
static uint16_t read_register_16(i2c_dev_t* i2c_dev, uint8_t low_register_addr) static uint16_t read_register_16(i2c_dev_t *i2c_dev, uint8_t low_register_addr)
{ {
uint16_t value = 0; uint16_t value = 0;
uint8_t data[2]; uint8_t data[2];
@ -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]);
@ -130,12 +137,12 @@ static uint16_t read_register_16(i2c_dev_t* i2c_dev, uint8_t low_register_addr)
return value; return value;
} }
static int enable(i2c_dev_t* i2c_dev) static int enable(i2c_dev_t *i2c_dev)
{ {
return write_register(i2c_dev, TSL2561_REG_CONTROL, TSL2561_ON); return write_register(i2c_dev, TSL2561_REG_CONTROL, TSL2561_ON);
} }
static int disable(i2c_dev_t* i2c_dev) static int disable(i2c_dev_t *i2c_dev)
{ {
return write_register(i2c_dev, TSL2561_REG_CONTROL, TSL2561_OFF); return write_register(i2c_dev, TSL2561_REG_CONTROL, TSL2561_OFF);
} }
@ -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;

View file

@ -26,13 +26,13 @@
#define TSL4531_INTEGRATION_TIME_200MS 240 #define TSL4531_INTEGRATION_TIME_200MS 240
#define TSL4531_INTEGRATION_TIME_400MS 480 // Default #define TSL4531_INTEGRATION_TIME_400MS 480 // Default
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 = TSL4531_REG_COMMAND | reg; reg = TSL4531_REG_COMMAND | reg;
return i2c_slave_write(i2c_dev->bus, i2c_dev->addr, &reg, &value, 1); return i2c_slave_write(i2c_dev->bus, i2c_dev->addr, &reg, &value, 1);
} }
static uint8_t read_register(i2c_dev_t* i2c_dev, uint8_t reg) static uint8_t read_register(i2c_dev_t *i2c_dev, uint8_t reg)
{ {
uint8_t data[1]; uint8_t data[1];
reg = TSL4531_REG_COMMAND | reg; reg = TSL4531_REG_COMMAND | reg;
@ -45,7 +45,7 @@ static uint8_t read_register(i2c_dev_t* i2c_dev, uint8_t reg)
return data[0]; return data[0];
} }
static uint16_t read_register_16(i2c_dev_t* i2c_dev, uint8_t low_register_addr) static uint16_t read_register_16(i2c_dev_t *i2c_dev, uint8_t low_register_addr)
{ {
uint16_t value = 0; uint16_t value = 0;
uint8_t data[2]; uint8_t data[2];