Code formatted, minor fixes (#466)
This commit is contained in:
parent
8a474d749d
commit
5fa48d0298
28 changed files with 623 additions and 608 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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))
|
||||||
{
|
{
|
||||||
|
|
|
@ -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, ®, (uint8_t *)&res, 2))
|
if (i2c_slave_read(dev->bus, dev->addr, ®, (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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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, ®, d, 2)))
|
if ((error = i2c_slave_read(dev->bus, dev->addr, ®, 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, ®, &cmd, 1);
|
return i2c_slave_write(dev->bus, dev->addr, ®, &cmd, 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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_
|
||||||
|
|
|
@ -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, ®, &val, 1);
|
i2c_slave_read(dev->bus, dev->addr, ®, &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, ®, &buf, 1);
|
i2c_slave_write(dev->bus, dev->addr, ®, &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, ® , buf, 7);
|
i2c_slave_read(dev->bus, dev->addr, ®, 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, ®, buf, len);
|
return i2c_slave_read(dev->bus, dev->addr, ®, 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, ®, buf, len);
|
return i2c_slave_write(dev->bus, dev->addr, ®, buf, len);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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, ®, &val, 1);
|
i2c_slave_write(dev->bus, dev->addr, ®, &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, ®, &res, 1);
|
i2c_slave_read(dev->bus, dev->addr, ®, &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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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, ®, d, sizeof(d));
|
return i2c_slave_write(dev->bus, dev->addr, ®, 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, ®, d, sizeof(d))
|
int error = i2c_slave_read(dev->bus, dev->addr, ®, d, sizeof(d));
|
||||||
debug("Data read from bus %u at %02X: %02X+%04X\n",dev->bus, dev->addr, reg, *value);
|
debug("Data read from bus %u at %02X: %02X+%04X\n", dev->bus, dev->addr, reg, *value);
|
||||||
*value = d[1] | (d[0] << 8);
|
*value = d[1] | (d[0] << 8);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
@ -53,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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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, ®, tmp, 2))
|
if (i2c_slave_read(dev->i2c_dev.bus, dev->i2c_dev.addr, ®, 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, ®, tmp, 2))
|
if (i2c_slave_read(dev->i2c_dev.bus, dev->i2c_dev.addr, ®, 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, ®, tmp, 2))
|
if (i2c_slave_read(dev->i2c_dev.bus, dev->i2c_dev.addr, ®, 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, ®, tmp, 2))
|
if (i2c_slave_read(dev->i2c_dev.bus, dev->i2c_dev.addr, ®, 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, ®, tmp, 2))
|
if (i2c_slave_read(dev->i2c_dev.bus, dev->i2c_dev.addr, ®, 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, ®, tmp, 2))
|
if (i2c_slave_read(dev->i2c_dev.bus, dev->i2c_dev.addr, ®, 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, ®, tmp, 3))
|
if (i2c_slave_read(i2c_dev->bus, i2c_dev->addr, ®, tmp, 3))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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];
|
||||||
|
|
|
@ -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, ®, &val, 1))
|
if (i2c_slave_write(dev->bus, dev->addr, ®, &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, ®, &res, 1))
|
if (i2c_slave_read(dev->bus, dev->addr, ®, &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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
|
@ -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 , ®, data, len);
|
return i2c_slave_write(dev->i2c_dev.bus, dev->i2c_dev.addr, ®, 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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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, ®, &value, 1);
|
return i2c_slave_write(i2c_dev->bus, i2c_dev->addr, ®, &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, ®, data, 1))
|
if (i2c_slave_read(i2c_dev->bus, i2c_dev->addr, ®, data, 1))
|
||||||
{
|
{
|
||||||
printf("Error in tsl2561 read_register\n");
|
debug("Error in tsl2561 read_register\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
return data[0];
|
return data[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
|
|
@ -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, ®, &value, 1);
|
return i2c_slave_write(i2c_dev->bus, i2c_dev->addr, ®, &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];
|
||||||
|
|
Loading…
Reference in a new issue