API HAL I2C: add timeout support. Update I2C API usage by drivers. (#374)
* API HAL I2C: add timeout support. Update I2C API usage by drivers. * F4: Add missing API HAL Vibro implementation.
This commit is contained in:
parent
468ee09785
commit
2f14f6dac5
@ -4,6 +4,7 @@
|
|||||||
#include <stm32wbxx_ll_i2c.h>
|
#include <stm32wbxx_ll_i2c.h>
|
||||||
#include <stm32wbxx_ll_rcc.h>
|
#include <stm32wbxx_ll_rcc.h>
|
||||||
#include <stm32wbxx_ll_gpio.h>
|
#include <stm32wbxx_ll_gpio.h>
|
||||||
|
#include <stm32wbxx_ll_cortex.h>
|
||||||
|
|
||||||
void api_hal_i2c_init() {
|
void api_hal_i2c_init() {
|
||||||
LL_I2C_InitTypeDef I2C_InitStruct = {0};
|
LL_I2C_InitTypeDef I2C_InitStruct = {0};
|
||||||
@ -37,7 +38,15 @@ void api_hal_i2c_init() {
|
|||||||
LL_I2C_EnableClockStretching(I2C1);
|
LL_I2C_EnableClockStretching(I2C1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void api_hal_i2c_tx(I2C_TypeDef* instance, uint8_t address, const uint8_t* data, uint8_t size) {
|
bool api_hal_i2c_tx(
|
||||||
|
I2C_TypeDef* instance,
|
||||||
|
uint8_t address,
|
||||||
|
const uint8_t* data,
|
||||||
|
uint8_t size,
|
||||||
|
uint32_t timeout) {
|
||||||
|
uint32_t time_left = timeout;
|
||||||
|
bool ret = true;
|
||||||
|
|
||||||
LL_I2C_HandleTransfer(
|
LL_I2C_HandleTransfer(
|
||||||
instance,
|
instance,
|
||||||
address,
|
address,
|
||||||
@ -49,13 +58,30 @@ void api_hal_i2c_tx(I2C_TypeDef* instance, uint8_t address, const uint8_t* data,
|
|||||||
while(!LL_I2C_IsActiveFlag_STOP(instance)) {
|
while(!LL_I2C_IsActiveFlag_STOP(instance)) {
|
||||||
if(LL_I2C_IsActiveFlag_TXIS(instance)) {
|
if(LL_I2C_IsActiveFlag_TXIS(instance)) {
|
||||||
LL_I2C_TransmitData8(instance, (*data++));
|
LL_I2C_TransmitData8(instance, (*data++));
|
||||||
|
time_left = timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(LL_SYSTICK_IsActiveCounterFlag()) {
|
||||||
|
if(--time_left == 0) {
|
||||||
|
ret = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LL_I2C_ClearFlag_STOP(instance);
|
LL_I2C_ClearFlag_STOP(instance);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void api_hal_i2c_rx(I2C_TypeDef* instance, uint8_t address, uint8_t* data, uint8_t size) {
|
bool api_hal_i2c_rx(
|
||||||
|
I2C_TypeDef* instance,
|
||||||
|
uint8_t address,
|
||||||
|
uint8_t* data,
|
||||||
|
uint8_t size,
|
||||||
|
uint32_t timeout) {
|
||||||
|
uint32_t time_left = timeout;
|
||||||
|
bool ret = true;
|
||||||
|
|
||||||
LL_I2C_HandleTransfer(
|
LL_I2C_HandleTransfer(
|
||||||
instance,
|
instance,
|
||||||
address,
|
address,
|
||||||
@ -67,19 +93,33 @@ void api_hal_i2c_rx(I2C_TypeDef* instance, uint8_t address, uint8_t* data, uint8
|
|||||||
while(!LL_I2C_IsActiveFlag_STOP(instance)) {
|
while(!LL_I2C_IsActiveFlag_STOP(instance)) {
|
||||||
if(LL_I2C_IsActiveFlag_RXNE(instance)) {
|
if(LL_I2C_IsActiveFlag_RXNE(instance)) {
|
||||||
*data++ = LL_I2C_ReceiveData8(instance);
|
*data++ = LL_I2C_ReceiveData8(instance);
|
||||||
|
time_left = timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(LL_SYSTICK_IsActiveCounterFlag()) {
|
||||||
|
if(--time_left == 0) {
|
||||||
|
ret = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LL_I2C_ClearFlag_STOP(instance);
|
LL_I2C_ClearFlag_STOP(instance);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void api_hal_i2c_trx(
|
bool api_hal_i2c_trx(
|
||||||
I2C_TypeDef* instance,
|
I2C_TypeDef* instance,
|
||||||
uint8_t address,
|
uint8_t address,
|
||||||
const uint8_t* tx_data,
|
const uint8_t* tx_data,
|
||||||
uint8_t tx_size,
|
uint8_t tx_size,
|
||||||
uint8_t* rx_data,
|
uint8_t* rx_data,
|
||||||
uint8_t rx_size) {
|
uint8_t rx_size,
|
||||||
api_hal_i2c_tx(instance, address, tx_data, tx_size);
|
uint32_t timeout) {
|
||||||
api_hal_i2c_rx(instance, address, rx_data, rx_size);
|
if(api_hal_i2c_tx(instance, address, tx_data, tx_size, timeout) &&
|
||||||
|
api_hal_i2c_rx(instance, address, rx_data, rx_size, timeout)) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,25 +10,28 @@ extern "C" {
|
|||||||
|
|
||||||
void api_hal_i2c_init();
|
void api_hal_i2c_init();
|
||||||
|
|
||||||
void api_hal_i2c_tx(
|
bool api_hal_i2c_tx(
|
||||||
I2C_TypeDef* instance,
|
I2C_TypeDef* instance,
|
||||||
const uint8_t address,
|
const uint8_t address,
|
||||||
const uint8_t* data,
|
const uint8_t* data,
|
||||||
const uint8_t size);
|
const uint8_t size,
|
||||||
|
uint32_t timeout);
|
||||||
|
|
||||||
void api_hal_i2c_rx(
|
bool api_hal_i2c_rx(
|
||||||
I2C_TypeDef* instance,
|
I2C_TypeDef* instance,
|
||||||
const uint8_t address,
|
const uint8_t address,
|
||||||
uint8_t* data,
|
uint8_t* data,
|
||||||
const uint8_t size);
|
const uint8_t size,
|
||||||
|
uint32_t timeout);
|
||||||
|
|
||||||
void api_hal_i2c_trx(
|
bool api_hal_i2c_trx(
|
||||||
I2C_TypeDef* instance,
|
I2C_TypeDef* instance,
|
||||||
const uint8_t address,
|
const uint8_t address,
|
||||||
const uint8_t* tx_data,
|
const uint8_t* tx_data,
|
||||||
const uint8_t tx_size,
|
const uint8_t tx_size,
|
||||||
uint8_t* rx_data,
|
uint8_t* rx_data,
|
||||||
const uint8_t rx_size);
|
const uint8_t rx_size,
|
||||||
|
uint32_t timeout);
|
||||||
|
|
||||||
#define with_api_hal_i2c(type, pointer, function_body) \
|
#define with_api_hal_i2c(type, pointer, function_body) \
|
||||||
{ \
|
{ \
|
||||||
|
@ -10,25 +10,38 @@ extern "C" {
|
|||||||
|
|
||||||
void api_hal_i2c_init();
|
void api_hal_i2c_init();
|
||||||
|
|
||||||
void api_hal_i2c_tx(I2C_TypeDef* instance, const uint8_t address, const uint8_t *data, const uint8_t size);
|
bool api_hal_i2c_tx(
|
||||||
|
I2C_TypeDef* instance,
|
||||||
|
const uint8_t address,
|
||||||
|
const uint8_t* data,
|
||||||
|
const uint8_t size,
|
||||||
|
uint32_t timeout);
|
||||||
|
|
||||||
void api_hal_i2c_rx(I2C_TypeDef* instance, const uint8_t address, uint8_t *data, const uint8_t size);
|
bool api_hal_i2c_rx(
|
||||||
|
I2C_TypeDef* instance,
|
||||||
|
const uint8_t address,
|
||||||
|
uint8_t* data,
|
||||||
|
const uint8_t size,
|
||||||
|
uint32_t timeout);
|
||||||
|
|
||||||
void api_hal_i2c_trx(
|
bool api_hal_i2c_trx(
|
||||||
I2C_TypeDef* instance, const uint8_t address,
|
I2C_TypeDef* instance,
|
||||||
const uint8_t *tx_data, const uint8_t tx_size,
|
const uint8_t address,
|
||||||
uint8_t *rx_data, const uint8_t rx_size
|
const uint8_t* tx_data,
|
||||||
);
|
const uint8_t tx_size,
|
||||||
|
uint8_t* rx_data,
|
||||||
|
const uint8_t rx_size,
|
||||||
|
uint32_t timeout);
|
||||||
|
|
||||||
void api_hal_i2c_lock();
|
void api_hal_i2c_lock();
|
||||||
|
|
||||||
void api_hal_i2c_unlock();
|
void api_hal_i2c_unlock();
|
||||||
|
|
||||||
#define with_api_hal_i2c(type, pointer, function_body) \
|
#define with_api_hal_i2c(type, pointer, function_body) \
|
||||||
{ \
|
{ \
|
||||||
api_hal_i2c_lock(); \
|
api_hal_i2c_lock(); \
|
||||||
*pointer = ({ type __fn__ function_body __fn__; })(); \
|
*pointer = ({ type __fn__ function_body __fn__; })(); \
|
||||||
api_hal_i2c_unlock(); \
|
api_hal_i2c_unlock(); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include <api-hal-i2c.h>
|
#include <api-hal-i2c.h>
|
||||||
#include <stm32wbxx_ll_i2c.h>
|
#include <stm32wbxx_ll_i2c.h>
|
||||||
#include <stm32wbxx_ll_gpio.h>
|
#include <stm32wbxx_ll_gpio.h>
|
||||||
|
#include <stm32wbxx_ll_cortex.h>
|
||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
|
|
||||||
osMutexId_t api_hal_i2c_mutex = NULL;
|
osMutexId_t api_hal_i2c_mutex = NULL;
|
||||||
@ -40,33 +41,90 @@ void api_hal_i2c_init() {
|
|||||||
LL_I2C_EnableClockStretching(I2C1);
|
LL_I2C_EnableClockStretching(I2C1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void api_hal_i2c_tx(I2C_TypeDef* instance, uint8_t address, const uint8_t *data, uint8_t size) {
|
bool api_hal_i2c_tx(
|
||||||
LL_I2C_HandleTransfer(instance, address, LL_I2C_ADDRSLAVE_7BIT, size, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_WRITE);
|
I2C_TypeDef* instance,
|
||||||
|
uint8_t address,
|
||||||
|
const uint8_t* data,
|
||||||
|
uint8_t size,
|
||||||
|
uint32_t timeout) {
|
||||||
|
uint32_t time_left = timeout;
|
||||||
|
bool ret = true;
|
||||||
|
|
||||||
while (!LL_I2C_IsActiveFlag_STOP(instance)) {
|
LL_I2C_HandleTransfer(
|
||||||
if (LL_I2C_IsActiveFlag_TXIS(instance)) {
|
instance,
|
||||||
|
address,
|
||||||
|
LL_I2C_ADDRSLAVE_7BIT,
|
||||||
|
size,
|
||||||
|
LL_I2C_MODE_AUTOEND,
|
||||||
|
LL_I2C_GENERATE_START_WRITE);
|
||||||
|
|
||||||
|
while(!LL_I2C_IsActiveFlag_STOP(instance)) {
|
||||||
|
if(LL_I2C_IsActiveFlag_TXIS(instance)) {
|
||||||
LL_I2C_TransmitData8(instance, (*data++));
|
LL_I2C_TransmitData8(instance, (*data++));
|
||||||
|
time_left = timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(LL_SYSTICK_IsActiveCounterFlag()) {
|
||||||
|
if(--time_left == 0) {
|
||||||
|
ret = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LL_I2C_ClearFlag_STOP(instance);
|
LL_I2C_ClearFlag_STOP(instance);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void api_hal_i2c_rx(I2C_TypeDef* instance, uint8_t address, uint8_t *data, uint8_t size) {
|
bool api_hal_i2c_rx(
|
||||||
LL_I2C_HandleTransfer(instance, address, LL_I2C_ADDRSLAVE_7BIT, size, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_READ);
|
I2C_TypeDef* instance,
|
||||||
|
uint8_t address,
|
||||||
|
uint8_t* data,
|
||||||
|
uint8_t size,
|
||||||
|
uint32_t timeout) {
|
||||||
|
uint32_t time_left = timeout;
|
||||||
|
bool ret = true;
|
||||||
|
|
||||||
while (!LL_I2C_IsActiveFlag_STOP(instance)) {
|
LL_I2C_HandleTransfer(
|
||||||
if (LL_I2C_IsActiveFlag_RXNE(instance)) {
|
instance,
|
||||||
|
address,
|
||||||
|
LL_I2C_ADDRSLAVE_7BIT,
|
||||||
|
size,
|
||||||
|
LL_I2C_MODE_AUTOEND,
|
||||||
|
LL_I2C_GENERATE_START_READ);
|
||||||
|
|
||||||
|
while(!LL_I2C_IsActiveFlag_STOP(instance)) {
|
||||||
|
if(LL_I2C_IsActiveFlag_RXNE(instance)) {
|
||||||
*data++ = LL_I2C_ReceiveData8(instance);
|
*data++ = LL_I2C_ReceiveData8(instance);
|
||||||
|
time_left = timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(LL_SYSTICK_IsActiveCounterFlag()) {
|
||||||
|
if(--time_left == 0) {
|
||||||
|
ret = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LL_I2C_ClearFlag_STOP(instance);
|
LL_I2C_ClearFlag_STOP(instance);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void api_hal_i2c_trx(I2C_TypeDef* instance, uint8_t address, const uint8_t *tx_data, uint8_t tx_size, uint8_t *rx_data, uint8_t rx_size) {
|
bool api_hal_i2c_trx(
|
||||||
api_hal_i2c_tx(instance, address, tx_data, tx_size);
|
I2C_TypeDef* instance,
|
||||||
api_hal_i2c_rx(instance, address, rx_data, rx_size);
|
uint8_t address,
|
||||||
|
const uint8_t* tx_data,
|
||||||
|
uint8_t tx_size,
|
||||||
|
uint8_t* rx_data,
|
||||||
|
uint8_t rx_size,
|
||||||
|
uint32_t timeout) {
|
||||||
|
if(api_hal_i2c_tx(instance, address, tx_data, tx_size, timeout) &&
|
||||||
|
api_hal_i2c_rx(instance, address, rx_data, rx_size, timeout)) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void api_hal_i2c_lock() {
|
void api_hal_i2c_lock() {
|
||||||
|
11
firmware/targets/f4/api-hal/api-hal-vibro.c
Normal file
11
firmware/targets/f4/api-hal/api-hal-vibro.c
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#include <api-hal-vibro.h>
|
||||||
|
#include <api-hal-gpio.h>
|
||||||
|
|
||||||
|
void api_hal_vibro_init() {
|
||||||
|
hal_gpio_init(&vibro_gpio, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow);
|
||||||
|
hal_gpio_write(&vibro_gpio, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void api_hal_vibro_on(bool value) {
|
||||||
|
hal_gpio_write(&vibro_gpio, value);
|
||||||
|
}
|
@ -7,4 +7,5 @@ void api_hal_init() {
|
|||||||
api_hal_i2c_init();
|
api_hal_i2c_init();
|
||||||
api_hal_power_init();
|
api_hal_power_init();
|
||||||
api_hal_light_init();
|
api_hal_light_init();
|
||||||
|
api_hal_vibro_init();
|
||||||
}
|
}
|
@ -1,6 +1,7 @@
|
|||||||
#include <api-hal-i2c.h>
|
#include <api-hal-i2c.h>
|
||||||
#include <stm32wbxx_ll_i2c.h>
|
#include <stm32wbxx_ll_i2c.h>
|
||||||
#include <stm32wbxx_ll_gpio.h>
|
#include <stm32wbxx_ll_gpio.h>
|
||||||
|
#include <stm32wbxx_ll_cortex.h>
|
||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
|
|
||||||
osMutexId_t api_hal_i2c_mutex = NULL;
|
osMutexId_t api_hal_i2c_mutex = NULL;
|
||||||
@ -40,33 +41,90 @@ void api_hal_i2c_init() {
|
|||||||
LL_I2C_EnableClockStretching(I2C1);
|
LL_I2C_EnableClockStretching(I2C1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void api_hal_i2c_tx(I2C_TypeDef* instance, uint8_t address, const uint8_t *data, uint8_t size) {
|
bool api_hal_i2c_tx(
|
||||||
LL_I2C_HandleTransfer(instance, address, LL_I2C_ADDRSLAVE_7BIT, size, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_WRITE);
|
I2C_TypeDef* instance,
|
||||||
|
uint8_t address,
|
||||||
|
const uint8_t* data,
|
||||||
|
uint8_t size,
|
||||||
|
uint32_t timeout) {
|
||||||
|
uint32_t time_left = timeout;
|
||||||
|
bool ret = true;
|
||||||
|
|
||||||
while (!LL_I2C_IsActiveFlag_STOP(instance)) {
|
LL_I2C_HandleTransfer(
|
||||||
if (LL_I2C_IsActiveFlag_TXIS(instance)) {
|
instance,
|
||||||
|
address,
|
||||||
|
LL_I2C_ADDRSLAVE_7BIT,
|
||||||
|
size,
|
||||||
|
LL_I2C_MODE_AUTOEND,
|
||||||
|
LL_I2C_GENERATE_START_WRITE);
|
||||||
|
|
||||||
|
while(!LL_I2C_IsActiveFlag_STOP(instance)) {
|
||||||
|
if(LL_I2C_IsActiveFlag_TXIS(instance)) {
|
||||||
LL_I2C_TransmitData8(instance, (*data++));
|
LL_I2C_TransmitData8(instance, (*data++));
|
||||||
|
time_left = timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(LL_SYSTICK_IsActiveCounterFlag()) {
|
||||||
|
if(--time_left == 0) {
|
||||||
|
ret = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LL_I2C_ClearFlag_STOP(instance);
|
LL_I2C_ClearFlag_STOP(instance);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void api_hal_i2c_rx(I2C_TypeDef* instance, uint8_t address, uint8_t *data, uint8_t size) {
|
bool api_hal_i2c_rx(
|
||||||
LL_I2C_HandleTransfer(instance, address, LL_I2C_ADDRSLAVE_7BIT, size, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_READ);
|
I2C_TypeDef* instance,
|
||||||
|
uint8_t address,
|
||||||
|
uint8_t* data,
|
||||||
|
uint8_t size,
|
||||||
|
uint32_t timeout) {
|
||||||
|
uint32_t time_left = timeout;
|
||||||
|
bool ret = true;
|
||||||
|
|
||||||
while (!LL_I2C_IsActiveFlag_STOP(instance)) {
|
LL_I2C_HandleTransfer(
|
||||||
if (LL_I2C_IsActiveFlag_RXNE(instance)) {
|
instance,
|
||||||
|
address,
|
||||||
|
LL_I2C_ADDRSLAVE_7BIT,
|
||||||
|
size,
|
||||||
|
LL_I2C_MODE_AUTOEND,
|
||||||
|
LL_I2C_GENERATE_START_READ);
|
||||||
|
|
||||||
|
while(!LL_I2C_IsActiveFlag_STOP(instance)) {
|
||||||
|
if(LL_I2C_IsActiveFlag_RXNE(instance)) {
|
||||||
*data++ = LL_I2C_ReceiveData8(instance);
|
*data++ = LL_I2C_ReceiveData8(instance);
|
||||||
|
time_left = timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(LL_SYSTICK_IsActiveCounterFlag()) {
|
||||||
|
if(--time_left == 0) {
|
||||||
|
ret = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LL_I2C_ClearFlag_STOP(instance);
|
LL_I2C_ClearFlag_STOP(instance);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void api_hal_i2c_trx(I2C_TypeDef* instance, uint8_t address, const uint8_t *tx_data, uint8_t tx_size, uint8_t *rx_data, uint8_t rx_size) {
|
bool api_hal_i2c_trx(
|
||||||
api_hal_i2c_tx(instance, address, tx_data, tx_size);
|
I2C_TypeDef* instance,
|
||||||
api_hal_i2c_rx(instance, address, rx_data, rx_size);
|
uint8_t address,
|
||||||
|
const uint8_t* tx_data,
|
||||||
|
uint8_t tx_size,
|
||||||
|
uint8_t* rx_data,
|
||||||
|
uint8_t rx_size,
|
||||||
|
uint32_t timeout) {
|
||||||
|
if(api_hal_i2c_tx(instance, address, tx_data, tx_size, timeout) &&
|
||||||
|
api_hal_i2c_rx(instance, address, rx_data, rx_size, timeout)) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void api_hal_i2c_lock() {
|
void api_hal_i2c_lock() {
|
||||||
|
@ -5,21 +5,19 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
uint8_t bit_reverse(uint8_t b) {
|
uint8_t bit_reverse(uint8_t b) {
|
||||||
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
|
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
|
||||||
b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
|
b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
|
||||||
b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
|
b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bq25896_read(uint8_t address, uint8_t* data, size_t size) {
|
bool bq25896_read(uint8_t address, uint8_t* data, size_t size) {
|
||||||
bool ret;
|
bool ret;
|
||||||
with_api_hal_i2c(bool, &ret, (){
|
with_api_hal_i2c(
|
||||||
api_hal_i2c_trx(
|
bool, &ret, () {
|
||||||
POWER_I2C, BQ25896_ADDRESS,
|
return api_hal_i2c_trx(
|
||||||
&address, 1, data, size
|
POWER_I2C, BQ25896_ADDRESS, &address, 1, data, size, BQ25896_I2C_TIMEOUT);
|
||||||
);
|
});
|
||||||
return true;
|
|
||||||
});
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,12 +27,12 @@ bool bq25896_read_reg(uint8_t address, uint8_t* data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool bq25896_write_reg(uint8_t address, uint8_t* data) {
|
bool bq25896_write_reg(uint8_t address, uint8_t* data) {
|
||||||
uint8_t buffer[2] = { address, *data };
|
uint8_t buffer[2] = {address, *data};
|
||||||
bool ret;
|
bool ret;
|
||||||
with_api_hal_i2c(bool, &ret, (){
|
with_api_hal_i2c(
|
||||||
api_hal_i2c_tx(POWER_I2C, BQ25896_ADDRESS, buffer, 2);
|
bool, &ret, () {
|
||||||
return true;
|
return api_hal_i2c_tx(POWER_I2C, BQ25896_ADDRESS, buffer, 2, BQ25896_I2C_TIMEOUT);
|
||||||
});
|
});
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +81,7 @@ void bq25896_init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void bq25896_poweroff() {
|
void bq25896_poweroff() {
|
||||||
bq25896_regs.r09.BATFET_DIS=1;
|
bq25896_regs.r09.BATFET_DIS = 1;
|
||||||
bq25896_write_reg(0x09, (uint8_t*)&bq25896_regs.r09);
|
bq25896_write_reg(0x09, (uint8_t*)&bq25896_regs.r09);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,7 +103,7 @@ void bq25896_disable_otg() {
|
|||||||
|
|
||||||
uint16_t bq25896_get_vbus_voltage() {
|
uint16_t bq25896_get_vbus_voltage() {
|
||||||
bq25896_read_reg(0x11, (uint8_t*)&bq25896_regs.r11);
|
bq25896_read_reg(0x11, (uint8_t*)&bq25896_regs.r11);
|
||||||
if (bq25896_regs.r11.VBUS_GD) {
|
if(bq25896_regs.r11.VBUS_GD) {
|
||||||
return (uint16_t)bq25896_regs.r11.VBUSV * 100 + 2600;
|
return (uint16_t)bq25896_regs.r11.VBUSV * 100 + 2600;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
@ -129,5 +127,5 @@ uint16_t bq25896_get_vbat_current() {
|
|||||||
|
|
||||||
uint32_t bq25896_get_ntc_mpct() {
|
uint32_t bq25896_get_ntc_mpct() {
|
||||||
bq25896_read_reg(0x10, (uint8_t*)&bq25896_regs.r10);
|
bq25896_read_reg(0x10, (uint8_t*)&bq25896_regs.r10);
|
||||||
return (uint32_t)bq25896_regs.r10.TSPCT * 465+21000;
|
return (uint32_t)bq25896_regs.r10.TSPCT * 465 + 21000;
|
||||||
}
|
}
|
||||||
|
@ -8,105 +8,99 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define BQ25896_ADDRESS 0xD6
|
#define BQ25896_ADDRESS 0xD6
|
||||||
|
#define BQ25896_I2C_TIMEOUT 50
|
||||||
|
|
||||||
#define IILIM_1600 (1<<5)
|
#define IILIM_1600 (1 << 5)
|
||||||
#define IILIM_800 (1<<4)
|
#define IILIM_800 (1 << 4)
|
||||||
#define IILIM_400 (1<<3)
|
#define IILIM_400 (1 << 3)
|
||||||
#define IILIM_200 (1<<2)
|
#define IILIM_200 (1 << 2)
|
||||||
#define IILIM_100 (1<<1)
|
#define IILIM_100 (1 << 1)
|
||||||
#define IILIM_50 (1<<0)
|
#define IILIM_50 (1 << 0)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t IINLIM:6; // Input Current Limit, mA, offset: +100mA
|
uint8_t IINLIM : 6; // Input Current Limit, mA, offset: +100mA
|
||||||
bool EN_ILIM:1; // Enable ILIM Pin
|
bool EN_ILIM : 1; // Enable ILIM Pin
|
||||||
bool EN_HIZ:1; // Enable HIZ Mode
|
bool EN_HIZ : 1; // Enable HIZ Mode
|
||||||
} REG00;
|
} REG00;
|
||||||
|
|
||||||
|
#define VINDPM_OS_1600 (1 << 4)
|
||||||
#define VINDPM_OS_1600 (1<<4)
|
#define VINDPM_OS_800 (1 << 3)
|
||||||
#define VINDPM_OS_800 (1<<3)
|
#define VINDPM_OS_400 (1 << 2)
|
||||||
#define VINDPM_OS_400 (1<<2)
|
#define VINDPM_OS_200 (1 << 1)
|
||||||
#define VINDPM_OS_200 (1<<1)
|
#define VINDPM_OS_100 (1 << 0)
|
||||||
#define VINDPM_OS_100 (1<<0)
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
Bhot34 = 0b00, // – VBHOT1 Threshold (34.75%) (default)
|
Bhot34 = 0b00, // – VBHOT1 Threshold (34.75%) (default)
|
||||||
Bhot37 = 0b01, // – VBHOT0 Threshold (Typ. 37.75%)
|
Bhot37 = 0b01, // – VBHOT0 Threshold (Typ. 37.75%)
|
||||||
Bhot31 = 0b10, // – VBHOT2 Threshold (Typ. 31.25%)
|
Bhot31 = 0b10, // – VBHOT2 Threshold (Typ. 31.25%)
|
||||||
BhotDisable = 0b11, // – Disable boost mode thermal protection
|
BhotDisable = 0b11, // – Disable boost mode thermal protection
|
||||||
} Bhot;
|
} Bhot;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t VINDPM_OS:5; // Input Voltage Limit Offset, mV
|
uint8_t VINDPM_OS : 5; // Input Voltage Limit Offset, mV
|
||||||
bool BCOLD:1; // Boost Mode Cold Temperature Monitor Threshold
|
bool BCOLD : 1; // Boost Mode Cold Temperature Monitor Threshold
|
||||||
Bhot BHOT:2; // Boost Mode Hot Temperature Monitor Threshold
|
Bhot BHOT : 2; // Boost Mode Hot Temperature Monitor Threshold
|
||||||
} REG01;
|
} REG01;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool AUTO_DPDM_EN:1; // Automatic Input Detection Enable
|
bool AUTO_DPDM_EN : 1; // Automatic Input Detection Enable
|
||||||
bool FORCE_DPDM:1; // Force Input Detection
|
bool FORCE_DPDM : 1; // Force Input Detection
|
||||||
uint8_t RES:2; // Reserved
|
uint8_t RES : 2; // Reserved
|
||||||
bool ICO_EN:1; // Input Current Optimizer (ICO) Enable
|
bool ICO_EN : 1; // Input Current Optimizer (ICO) Enable
|
||||||
bool BOOST_FREQ:1; // Boost Mode Frequency Selection
|
bool BOOST_FREQ : 1; // Boost Mode Frequency Selection
|
||||||
bool CONV_RATE:1; // ADC Conversion Rate Selection
|
bool CONV_RATE : 1; // ADC Conversion Rate Selection
|
||||||
bool CONV_START:1; // ADC Conversion Start Control
|
bool CONV_START : 1; // ADC Conversion Start Control
|
||||||
} REG02;
|
} REG02;
|
||||||
|
|
||||||
|
#define SYS_MIN_400 (1 << 2)
|
||||||
#define SYS_MIN_400 (1<<2)
|
#define SYS_MIN_200 (1 << 1)
|
||||||
#define SYS_MIN_200 (1<<1)
|
#define SYS_MIN_100 (1 << 0)
|
||||||
#define SYS_MIN_100 (1<<0)
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool MIN_VBAT_SEL:1; // Minimum Battery Voltage (falling) to exit boost mode
|
bool MIN_VBAT_SEL : 1; // Minimum Battery Voltage (falling) to exit boost mode
|
||||||
uint8_t SYS_MIN:3; // Minimum System Voltage Limit, mV, offset: +3000mV
|
uint8_t SYS_MIN : 3; // Minimum System Voltage Limit, mV, offset: +3000mV
|
||||||
bool CHG_CONFIG:1; // Charge Enable Configuration
|
bool CHG_CONFIG : 1; // Charge Enable Configuration
|
||||||
bool OTG_CONFIG:1; // Boost (OTG) Mode Configuration
|
bool OTG_CONFIG : 1; // Boost (OTG) Mode Configuration
|
||||||
bool WD_RST:1; // I2C Watchdog Timer Reset
|
bool WD_RST : 1; // I2C Watchdog Timer Reset
|
||||||
bool BAT_LOADEN:1; // Battery Load (IBATLOAD) Enable
|
bool BAT_LOADEN : 1; // Battery Load (IBATLOAD) Enable
|
||||||
} REG03;
|
} REG03;
|
||||||
|
|
||||||
|
#define ICHG_4096 (1 << 6)
|
||||||
#define ICHG_4096 (1<<6)
|
#define ICHG_2048 (1 << 5)
|
||||||
#define ICHG_2048 (1<<5)
|
#define ICHG_1024 (1 << 4)
|
||||||
#define ICHG_1024 (1<<4)
|
#define ICHG_512 (1 << 3)
|
||||||
#define ICHG_512 (1<<3)
|
#define ICHG_256 (1 << 2)
|
||||||
#define ICHG_256 (1<<2)
|
#define ICHG_128 (1 << 1)
|
||||||
#define ICHG_128 (1<<1)
|
#define ICHG_64 (1 << 0)
|
||||||
#define ICHG_64 (1<<0)
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t ICHG:7; // Fast Charge Current Limit, mA
|
uint8_t ICHG : 7; // Fast Charge Current Limit, mA
|
||||||
bool EN_PUMPX:1; // Current pulse control Enable
|
bool EN_PUMPX : 1; // Current pulse control Enable
|
||||||
} REG04;
|
} REG04;
|
||||||
|
|
||||||
|
#define IPRETERM_512 (1 << 3)
|
||||||
#define IPRETERM_512 (1<<3)
|
#define IPRETERM_256 (1 << 2)
|
||||||
#define IPRETERM_256 (1<<2)
|
#define IPRETERM_128 (1 << 1)
|
||||||
#define IPRETERM_128 (1<<1)
|
#define IPRETERM_64 (1 << 0)
|
||||||
#define IPRETERM_64 (1<<0)
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t ITERM:4; // Termination Current Limit, offset: +64mA
|
uint8_t ITERM : 4; // Termination Current Limit, offset: +64mA
|
||||||
uint8_t IPRECHG:4; // Precharge Current Limit, offset: +64mA
|
uint8_t IPRECHG : 4; // Precharge Current Limit, offset: +64mA
|
||||||
} REG05;
|
} REG05;
|
||||||
|
|
||||||
|
#define VREG_512 (1 << 5)
|
||||||
#define VREG_512 (1<<5)
|
#define VREG_256 (1 << 4)
|
||||||
#define VREG_256 (1<<4)
|
#define VREG_128 (1 << 3)
|
||||||
#define VREG_128 (1<<3)
|
#define VREG_64 (1 << 2)
|
||||||
#define VREG_64 (1<<2)
|
#define VREG_32 (1 << 1)
|
||||||
#define VREG_32 (1<<1)
|
#define VREG_16 (1 << 0)
|
||||||
#define VREG_16 (1<<0)
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool VRECHG:1; // Battery Recharge Threshold Offset
|
bool VRECHG : 1; // Battery Recharge Threshold Offset
|
||||||
bool BATLOWV:1; // Battery Precharge to Fast Charge Threshold
|
bool BATLOWV : 1; // Battery Precharge to Fast Charge Threshold
|
||||||
uint8_t VREG:6; // Charge Voltage Limit, offset: +3840mV
|
uint8_t VREG : 6; // Charge Voltage Limit, offset: +3840mV
|
||||||
} REG06;
|
} REG06;
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
WatchdogDisable = 0b00,
|
WatchdogDisable = 0b00,
|
||||||
Watchdog40 = 0b01,
|
Watchdog40 = 0b01,
|
||||||
@ -122,68 +116,64 @@ typedef enum {
|
|||||||
} ChgTimer;
|
} ChgTimer;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool JEITA_ISET:1; // JEITA Low Temperature Current Setting
|
bool JEITA_ISET : 1; // JEITA Low Temperature Current Setting
|
||||||
ChgTimer CHG_TIMER:2; // Fast Charge Timer Setting
|
ChgTimer CHG_TIMER : 2; // Fast Charge Timer Setting
|
||||||
bool EN_TIMER:1; // Charging Safety Timer Enable
|
bool EN_TIMER : 1; // Charging Safety Timer Enable
|
||||||
Watchdog WATCHDOG:2; // I2C Watchdog Timer Setting
|
Watchdog WATCHDOG : 2; // I2C Watchdog Timer Setting
|
||||||
bool STAT_DIS:1; // STAT Pin Disable
|
bool STAT_DIS : 1; // STAT Pin Disable
|
||||||
bool EN_TERM:1; // Charging Termination Enable
|
bool EN_TERM : 1; // Charging Termination Enable
|
||||||
} REG07;
|
} REG07;
|
||||||
|
|
||||||
|
#define BAT_COMP_80 (1 << 2)
|
||||||
|
#define BAT_COMP_40 (1 << 1)
|
||||||
|
#define BAT_COMP_20 (1 << 0)
|
||||||
|
|
||||||
#define BAT_COMP_80 (1<<2)
|
#define VCLAMP_128 (1 << 2)
|
||||||
#define BAT_COMP_40 (1<<1)
|
#define VCLAMP_64 (1 << 1)
|
||||||
#define BAT_COMP_20 (1<<0)
|
#define VCLAMP_32 (1 << 0)
|
||||||
|
|
||||||
#define VCLAMP_128 (1<<2)
|
#define TREG_60 (0b00)
|
||||||
#define VCLAMP_64 (1<<1)
|
#define TREG_80 (0b01)
|
||||||
#define VCLAMP_32 (1<<0)
|
#define TREG_100 (0b10)
|
||||||
|
#define TREG_120 (0b11)
|
||||||
#define TREG_60 (0b00)
|
|
||||||
#define TREG_80 (0b01)
|
|
||||||
#define TREG_100 (0b10)
|
|
||||||
#define TREG_120 (0b11)
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t TREG:2; // Thermal Regulation Threshold
|
uint8_t TREG : 2; // Thermal Regulation Threshold
|
||||||
uint8_t VCLAMP:3; // IR Compensation Voltage Clamp
|
uint8_t VCLAMP : 3; // IR Compensation Voltage Clamp
|
||||||
uint8_t BAT_COMP:3; // IR Compensation Resistor Setting
|
uint8_t BAT_COMP : 3; // IR Compensation Resistor Setting
|
||||||
} REG08;
|
} REG08;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool PUMPX_DN:1; // Current pulse control voltage down enable
|
bool PUMPX_DN : 1; // Current pulse control voltage down enable
|
||||||
bool PUMPX_UP:1; // Current pulse control voltage up enable
|
bool PUMPX_UP : 1; // Current pulse control voltage up enable
|
||||||
bool BATFET_RST_EN:1; // BATFET full system reset enable
|
bool BATFET_RST_EN : 1; // BATFET full system reset enable
|
||||||
bool BATFET_DLY:1; // BATFET turn off delay control
|
bool BATFET_DLY : 1; // BATFET turn off delay control
|
||||||
bool JEITA_VSET:1; // JEITA High Temperature Voltage Setting
|
bool JEITA_VSET : 1; // JEITA High Temperature Voltage Setting
|
||||||
bool BATFET_DIS:1; // Force BATFET off to enable ship mode
|
bool BATFET_DIS : 1; // Force BATFET off to enable ship mode
|
||||||
bool TMR2X_EN:1; // Safety Timer Setting during DPM or Thermal Regulation
|
bool TMR2X_EN : 1; // Safety Timer Setting during DPM or Thermal Regulation
|
||||||
bool FORCE_ICO:1; // Force Start Input Current Optimizer
|
bool FORCE_ICO : 1; // Force Start Input Current Optimizer
|
||||||
} REG09;
|
} REG09;
|
||||||
|
|
||||||
|
#define BOOSTV_512 (1 << 3)
|
||||||
|
#define BOOSTV_256 (1 << 2)
|
||||||
|
#define BOOSTV_128 (1 << 1)
|
||||||
|
#define BOOSTV_64 (1 << 0)
|
||||||
|
|
||||||
#define BOOSTV_512 (1<<3)
|
#define BOOST_LIM_500 (0b000)
|
||||||
#define BOOSTV_256 (1<<2)
|
#define BOOST_LIM_750 (0b001)
|
||||||
#define BOOSTV_128 (1<<1)
|
#define BOOST_LIM_1200 (0b010)
|
||||||
#define BOOSTV_64 (1<<0)
|
#define BOOST_LIM_1400 (0b011)
|
||||||
|
#define BOOST_LIM_1650 (0b100)
|
||||||
#define BOOST_LIM_500 (0b000)
|
#define BOOST_LIM_1875 (0b101)
|
||||||
#define BOOST_LIM_750 (0b001)
|
#define BOOST_LIM_2150 (0b110)
|
||||||
#define BOOST_LIM_1200 (0b010)
|
#define BOOST_LIM_RSVD (0b111)
|
||||||
#define BOOST_LIM_1400 (0b011)
|
|
||||||
#define BOOST_LIM_1650 (0b100)
|
|
||||||
#define BOOST_LIM_1875 (0b101)
|
|
||||||
#define BOOST_LIM_2150 (0b110)
|
|
||||||
#define BOOST_LIM_RSVD (0b111)
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t BOOST_LIM:3; // Boost Mode Current Limit
|
uint8_t BOOST_LIM : 3; // Boost Mode Current Limit
|
||||||
bool PFM_OTG_DIS:1; // PFM mode allowed in boost mode
|
bool PFM_OTG_DIS : 1; // PFM mode allowed in boost mode
|
||||||
uint8_t BOOSTV:4; // Boost Mode Voltage Regulation, offset: +4550mV
|
uint8_t BOOSTV : 4; // Boost Mode Voltage Regulation, offset: +4550mV
|
||||||
} REG0A;
|
} REG0A;
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
VBusStatNo = 0b000,
|
VBusStatNo = 0b000,
|
||||||
VBusStatUSB = 0b001,
|
VBusStatUSB = 0b001,
|
||||||
@ -199,14 +189,13 @@ typedef enum {
|
|||||||
} ChrgStat;
|
} ChrgStat;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool VSYS_STAT:1; // VSYS Regulation Status
|
bool VSYS_STAT : 1; // VSYS Regulation Status
|
||||||
bool RES:1; // Reserved: Always reads 1
|
bool RES : 1; // Reserved: Always reads 1
|
||||||
bool PG_STAT:1; // Power Good Status
|
bool PG_STAT : 1; // Power Good Status
|
||||||
ChrgStat CHRG_STAT:2; // Charging Status
|
ChrgStat CHRG_STAT : 2; // Charging Status
|
||||||
VBusStat VBUS_STAT:3; // VBUS Status register
|
VBusStat VBUS_STAT : 3; // VBUS Status register
|
||||||
} REG0B;
|
} REG0B;
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ChrgFaultNO = 0b00,
|
ChrgFaultNO = 0b00,
|
||||||
ChrgFaultIN = 0b01,
|
ChrgFaultIN = 0b01,
|
||||||
@ -223,69 +212,62 @@ typedef enum {
|
|||||||
} NtcFault;
|
} NtcFault;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
NtcFault NTC_FAULT:3; // NTC Fault Status
|
NtcFault NTC_FAULT : 3; // NTC Fault Status
|
||||||
bool BAT_FAULT:1; // Battery Fault Status
|
bool BAT_FAULT : 1; // Battery Fault Status
|
||||||
ChrgFault CHRG_FAULT:2; // Charge Fault Status
|
ChrgFault CHRG_FAULT : 2; // Charge Fault Status
|
||||||
bool BOOST_FAULT:1; // Boost Mode Fault Status
|
bool BOOST_FAULT : 1; // Boost Mode Fault Status
|
||||||
bool WATCHDOG_FAULT:1; // Watchdog Fault Status
|
bool WATCHDOG_FAULT : 1; // Watchdog Fault Status
|
||||||
} REG0C;
|
} REG0C;
|
||||||
|
|
||||||
|
#define VINDPM_6400 (1 << 6)
|
||||||
#define VINDPM_6400 (1<<6)
|
#define VINDPM_3200 (1 << 5)
|
||||||
#define VINDPM_3200 (1<<5)
|
#define VINDPM_1600 (1 << 4)
|
||||||
#define VINDPM_1600 (1<<4)
|
#define VINDPM_800 (1 << 3)
|
||||||
#define VINDPM_800 (1<<3)
|
#define VINDPM_400 (1 << 2)
|
||||||
#define VINDPM_400 (1<<2)
|
#define VINDPM_200 (1 << 1)
|
||||||
#define VINDPM_200 (1<<1)
|
#define VINDPM_100 (1 << 0)
|
||||||
#define VINDPM_100 (1<<0)
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t VINDPM:7; // Absolute VINDPM Threshold, offset: +2600mV
|
uint8_t VINDPM : 7; // Absolute VINDPM Threshold, offset: +2600mV
|
||||||
bool FORCE_VINDPM:1; // VINDPM Threshold Setting Method
|
bool FORCE_VINDPM : 1; // VINDPM Threshold Setting Method
|
||||||
} REG0D;
|
} REG0D;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t BATV:7; // ADC conversion of Battery Voltage (VBAT), offset: +2304mV
|
uint8_t BATV : 7; // ADC conversion of Battery Voltage (VBAT), offset: +2304mV
|
||||||
bool THERM_STAT:1; // Thermal Regulation Status
|
bool THERM_STAT : 1; // Thermal Regulation Status
|
||||||
} REG0E;
|
} REG0E;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t SYSV:7; // ADDC conversion of System Voltage (VSYS), offset: +2304mV
|
uint8_t SYSV : 7; // ADDC conversion of System Voltage (VSYS), offset: +2304mV
|
||||||
uint8_t RES:1; // Reserved: Always reads 0
|
uint8_t RES : 1; // Reserved: Always reads 0
|
||||||
} REG0F;
|
} REG0F;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t TSPCT:7; // ADC conversion of TS Voltage (TS) as percentage of REGN, offset: +21%
|
uint8_t TSPCT : 7; // ADC conversion of TS Voltage (TS) as percentage of REGN, offset: +21%
|
||||||
uint8_t RES:1; // Reserved: Always reads 0
|
uint8_t RES : 1; // Reserved: Always reads 0
|
||||||
} REG10;
|
} REG10;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t VBUSV:7; // ADC conversion of VBUS voltage (VBUS), offset: +2600mV
|
uint8_t VBUSV : 7; // ADC conversion of VBUS voltage (VBUS), offset: +2600mV
|
||||||
bool VBUS_GD:1; // VBUS Good Status
|
bool VBUS_GD : 1; // VBUS Good Status
|
||||||
} REG11;
|
} REG11;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t ICHGR:7; // ADC conversion of Charge Current (IBAT) when VBAT > VBATSHORT
|
uint8_t ICHGR : 7; // ADC conversion of Charge Current (IBAT) when VBAT > VBATSHORT
|
||||||
uint8_t RES:1; // Reserved: Always reads 0
|
uint8_t RES : 1; // Reserved: Always reads 0
|
||||||
} REG12;
|
} REG12;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t IDPM_LIM:6; // Input Current Limit in effect while Input Current Optimizer (ICO) is enabled, offset: 100mA (default)
|
uint8_t
|
||||||
bool IDPM_STAT:1; // IINDPM Status
|
IDPM_LIM : 6; // Input Current Limit in effect while Input Current Optimizer (ICO) is enabled, offset: 100mA (default)
|
||||||
bool VDPM_STAT:1; // VINDPM Status
|
bool IDPM_STAT : 1; // IINDPM Status
|
||||||
|
bool VDPM_STAT : 1; // VINDPM Status
|
||||||
} REG13;
|
} REG13;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t DEV_REV:2; // Device Revision
|
uint8_t DEV_REV : 2; // Device Revision
|
||||||
bool TS_PROFILE:1; // Temperature Profile
|
bool TS_PROFILE : 1; // Temperature Profile
|
||||||
uint8_t PN:3; // Device Configuration
|
uint8_t PN : 3; // Device Configuration
|
||||||
bool ICO_OPTIMIZED:1; // Input Current Optimizer (ICO) Status
|
bool ICO_OPTIMIZED : 1; // Input Current Optimizer (ICO) Status
|
||||||
bool REG_RST:1; // Register Reset
|
bool REG_RST : 1; // Register Reset
|
||||||
} REG14;
|
} REG14;
|
||||||
|
@ -5,28 +5,30 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
uint16_t bq27220_read_word(uint8_t address) {
|
uint16_t bq27220_read_word(uint8_t address) {
|
||||||
uint8_t buffer[2] = { address };
|
uint8_t buffer[2] = {address};
|
||||||
uint16_t ret;
|
uint16_t ret;
|
||||||
with_api_hal_i2c(uint16_t, &ret, (){
|
with_api_hal_i2c(
|
||||||
api_hal_i2c_trx(
|
uint16_t, &ret, () {
|
||||||
POWER_I2C, BQ27220_ADDRESS,
|
if(api_hal_i2c_trx(
|
||||||
buffer, 1, buffer, 2
|
POWER_I2C, BQ27220_ADDRESS, buffer, 1, buffer, 2, BQ27220_I2C_TIMEOUT)) {
|
||||||
);
|
return *(uint16_t*)buffer;
|
||||||
return *(uint16_t*)buffer;
|
} else {
|
||||||
});
|
return 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bq27220_control(uint16_t control) {
|
bool bq27220_control(uint16_t control) {
|
||||||
bool ret;
|
bool ret;
|
||||||
with_api_hal_i2c(bool, &ret, (){
|
with_api_hal_i2c(
|
||||||
uint8_t buffer[3];
|
bool, &ret, () {
|
||||||
buffer[0] = CommandControl;
|
uint8_t buffer[3];
|
||||||
buffer[1] = (control>>8) & 0xFF;
|
buffer[0] = CommandControl;
|
||||||
buffer[2] = control & 0xFF;
|
buffer[1] = (control >> 8) & 0xFF;
|
||||||
api_hal_i2c_tx(POWER_I2C, BQ27220_ADDRESS, buffer, 3);
|
buffer[2] = control & 0xFF;
|
||||||
return true;
|
return api_hal_i2c_tx(POWER_I2C, BQ27220_ADDRESS, buffer, 3, BQ27220_I2C_TIMEOUT);
|
||||||
});
|
});
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,7 +48,7 @@ int16_t bq27220_get_current() {
|
|||||||
|
|
||||||
uint8_t bq27220_get_battery_status(BatteryStatus* battery_status) {
|
uint8_t bq27220_get_battery_status(BatteryStatus* battery_status) {
|
||||||
uint16_t data = bq27220_read_word(CommandBatteryStatus);
|
uint16_t data = bq27220_read_word(CommandBatteryStatus);
|
||||||
if (data == BQ27220_ERROR) {
|
if(data == BQ27220_ERROR) {
|
||||||
return BQ27220_ERROR;
|
return BQ27220_ERROR;
|
||||||
} else {
|
} else {
|
||||||
*(uint16_t*)battery_status = data;
|
*(uint16_t*)battery_status = data;
|
||||||
@ -56,7 +58,7 @@ uint8_t bq27220_get_battery_status(BatteryStatus* battery_status) {
|
|||||||
|
|
||||||
uint8_t bq27220_get_operation_status(OperationStatus* operation_status) {
|
uint8_t bq27220_get_operation_status(OperationStatus* operation_status) {
|
||||||
uint16_t data = bq27220_read_word(CommandOperationStatus);
|
uint16_t data = bq27220_read_word(CommandOperationStatus);
|
||||||
if (data == BQ27220_ERROR) {
|
if(data == BQ27220_ERROR) {
|
||||||
return BQ27220_ERROR;
|
return BQ27220_ERROR;
|
||||||
} else {
|
} else {
|
||||||
*(uint16_t*)operation_status = data;
|
*(uint16_t*)operation_status = data;
|
||||||
|
@ -8,39 +8,39 @@
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
// Low byte, Low bit first
|
// Low byte, Low bit first
|
||||||
bool DSG:1; // The device is in DISCHARGE
|
bool DSG : 1; // The device is in DISCHARGE
|
||||||
bool SYSDWN:1; // System down bit indicating the system should shut down
|
bool SYSDWN : 1; // System down bit indicating the system should shut down
|
||||||
bool TDA:1; // Terminate Discharge Alarm
|
bool TDA : 1; // Terminate Discharge Alarm
|
||||||
bool BATTPRES:1; // Battery Present detected
|
bool BATTPRES : 1; // Battery Present detected
|
||||||
bool AUTH_GD:1; // Detect inserted battery
|
bool AUTH_GD : 1; // Detect inserted battery
|
||||||
bool OCVGD:1; // Good OCV measurement taken
|
bool OCVGD : 1; // Good OCV measurement taken
|
||||||
bool TCA:1; // Terminate Charge Alarm
|
bool TCA : 1; // Terminate Charge Alarm
|
||||||
bool RSVD:1; // Reserved
|
bool RSVD : 1; // Reserved
|
||||||
// High byte, Low bit first
|
// High byte, Low bit first
|
||||||
bool CHGINH:1; // Charge inhibit
|
bool CHGINH : 1; // Charge inhibit
|
||||||
bool FC:1; // Full-charged is detected
|
bool FC : 1; // Full-charged is detected
|
||||||
bool OTD:1; // Overtemperature in discharge condition is detected
|
bool OTD : 1; // Overtemperature in discharge condition is detected
|
||||||
bool OTC:1; // Overtemperature in charge condition is detected
|
bool OTC : 1; // Overtemperature in charge condition is detected
|
||||||
bool SLEEP:1; // Device is operating in SLEEP mode when set
|
bool SLEEP : 1; // Device is operating in SLEEP mode when set
|
||||||
bool OCVFAIL:1; // Status bit indicating that the OCV reading failed due to current
|
bool OCVFAIL : 1; // Status bit indicating that the OCV reading failed due to current
|
||||||
bool OCVCOMP:1; // An OCV measurement update is complete
|
bool OCVCOMP : 1; // An OCV measurement update is complete
|
||||||
bool FD:1; // Full-discharge is detected
|
bool FD : 1; // Full-discharge is detected
|
||||||
} BatteryStatus;
|
} BatteryStatus;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
// Low byte, Low bit first
|
// Low byte, Low bit first
|
||||||
bool CALMD:1;
|
bool CALMD : 1;
|
||||||
bool SEC0:1;
|
bool SEC0 : 1;
|
||||||
bool SEC1:1;
|
bool SEC1 : 1;
|
||||||
bool EDV2:1;
|
bool EDV2 : 1;
|
||||||
bool VDQ:1;
|
bool VDQ : 1;
|
||||||
bool INITCOMP:1;
|
bool INITCOMP : 1;
|
||||||
bool SMTH:1;
|
bool SMTH : 1;
|
||||||
bool BTPINT:1;
|
bool BTPINT : 1;
|
||||||
// High byte, Low bit first
|
// High byte, Low bit first
|
||||||
uint8_t RSVD1:2;
|
uint8_t RSVD1 : 2;
|
||||||
bool CFGUPDATE:1;
|
bool CFGUPDATE : 1;
|
||||||
uint8_t RSVD0:5;
|
uint8_t RSVD0 : 5;
|
||||||
} OperationStatus;
|
} OperationStatus;
|
||||||
|
|
||||||
/* Initialize Driver */
|
/* Initialize Driver */
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define BQ27220_ADDRESS 0xAA
|
#define BQ27220_ADDRESS 0xAA
|
||||||
|
#define BQ27220_I2C_TIMEOUT 50
|
||||||
|
|
||||||
#define CommandControl 0x00
|
#define CommandControl 0x00
|
||||||
#define CommandAtRate 0x02
|
#define CommandAtRate 0x02
|
||||||
|
@ -4,25 +4,25 @@
|
|||||||
#include <api-hal-i2c.h>
|
#include <api-hal-i2c.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
bool lp5562_write_reg(uint8_t address, uint8_t *data) {
|
bool lp5562_write_reg(uint8_t address, uint8_t* data) {
|
||||||
uint8_t buffer[2] = { address, *data };
|
uint8_t buffer[2] = {address, *data};
|
||||||
bool ret;
|
bool ret;
|
||||||
with_api_hal_i2c(bool, &ret, (){
|
with_api_hal_i2c(
|
||||||
api_hal_i2c_tx(POWER_I2C, LP5562_ADDRESS, buffer, 2);
|
bool, &ret, () {
|
||||||
return true;
|
return api_hal_i2c_tx(POWER_I2C, LP5562_ADDRESS, buffer, 2, LP5562_I2C_TIMEOUT);
|
||||||
});
|
});
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lp5562_reset() {
|
void lp5562_reset() {
|
||||||
Reg0D_Reset reg = {.value = 0xFF };
|
Reg0D_Reset reg = {.value = 0xFF};
|
||||||
lp5562_write_reg(0x0D, (uint8_t*)®);
|
lp5562_write_reg(0x0D, (uint8_t*)®);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lp5562_configure() {
|
void lp5562_configure() {
|
||||||
Reg08_Config config = { .INT_CLK_EN = true, .PS_EN = true, .PWM_HF = true };
|
Reg08_Config config = {.INT_CLK_EN = true, .PS_EN = true, .PWM_HF = true};
|
||||||
lp5562_write_reg(0x08, (uint8_t*)&config);
|
lp5562_write_reg(0x08, (uint8_t*)&config);
|
||||||
|
|
||||||
Reg70_LedMap map = {
|
Reg70_LedMap map = {
|
||||||
.red = EngSelectI2C,
|
.red = EngSelectI2C,
|
||||||
.green = EngSelectI2C,
|
.green = EngSelectI2C,
|
||||||
@ -33,19 +33,19 @@ void lp5562_configure() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void lp5562_enable() {
|
void lp5562_enable() {
|
||||||
Reg00_Enable reg = { .CHIP_EN = true, .LOG_EN = true };
|
Reg00_Enable reg = {.CHIP_EN = true, .LOG_EN = true};
|
||||||
lp5562_write_reg(0x00, (uint8_t*)®);
|
lp5562_write_reg(0x00, (uint8_t*)®);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lp5562_set_channel_current(LP5562Channel channel, uint8_t value) {
|
void lp5562_set_channel_current(LP5562Channel channel, uint8_t value) {
|
||||||
uint8_t reg_no;
|
uint8_t reg_no;
|
||||||
if (channel == LP5562ChannelRed) {
|
if(channel == LP5562ChannelRed) {
|
||||||
reg_no = 0x07;
|
reg_no = 0x07;
|
||||||
} else if (channel == LP5562ChannelGreen) {
|
} else if(channel == LP5562ChannelGreen) {
|
||||||
reg_no = 0x06;
|
reg_no = 0x06;
|
||||||
} else if (channel == LP5562ChannelBlue) {
|
} else if(channel == LP5562ChannelBlue) {
|
||||||
reg_no = 0x05;
|
reg_no = 0x05;
|
||||||
} else if (channel == LP5562ChannelWhite) {
|
} else if(channel == LP5562ChannelWhite) {
|
||||||
reg_no = 0x0F;
|
reg_no = 0x0F;
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
@ -55,13 +55,13 @@ void lp5562_set_channel_current(LP5562Channel channel, uint8_t value) {
|
|||||||
|
|
||||||
void lp5562_set_channel_value(LP5562Channel channel, uint8_t value) {
|
void lp5562_set_channel_value(LP5562Channel channel, uint8_t value) {
|
||||||
uint8_t reg_no;
|
uint8_t reg_no;
|
||||||
if (channel == LP5562ChannelRed) {
|
if(channel == LP5562ChannelRed) {
|
||||||
reg_no = 0x04;
|
reg_no = 0x04;
|
||||||
} else if (channel == LP5562ChannelGreen) {
|
} else if(channel == LP5562ChannelGreen) {
|
||||||
reg_no = 0x03;
|
reg_no = 0x03;
|
||||||
} else if (channel == LP5562ChannelBlue) {
|
} else if(channel == LP5562ChannelBlue) {
|
||||||
reg_no = 0x02;
|
reg_no = 0x02;
|
||||||
} else if (channel == LP5562ChannelWhite) {
|
} else if(channel == LP5562ChannelWhite) {
|
||||||
reg_no = 0x0E;
|
reg_no = 0x0E;
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
|
@ -4,10 +4,10 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
LP5562ChannelRed,
|
LP5562ChannelRed,
|
||||||
LP5562ChannelGreen,
|
LP5562ChannelGreen,
|
||||||
LP5562ChannelBlue,
|
LP5562ChannelBlue,
|
||||||
LP5562ChannelWhite,
|
LP5562ChannelWhite,
|
||||||
} LP5562Channel;
|
} LP5562Channel;
|
||||||
|
|
||||||
/* Initialize Driver */
|
/* Initialize Driver */
|
||||||
|
@ -5,66 +5,67 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define LP5562_ADDRESS 0x60
|
#define LP5562_ADDRESS 0x60
|
||||||
|
#define LP5562_I2C_TIMEOUT 50
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EngExecHold=0b00,
|
EngExecHold = 0b00,
|
||||||
EngExecStep=0b01,
|
EngExecStep = 0b01,
|
||||||
EngExecRun=0b10,
|
EngExecRun = 0b10,
|
||||||
EngExecPC=0b11,
|
EngExecPC = 0b11,
|
||||||
} EngExec;
|
} EngExec;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
EngExec ENG3_EXEC:2;
|
EngExec ENG3_EXEC : 2;
|
||||||
EngExec ENG2_EXEC:2;
|
EngExec ENG2_EXEC : 2;
|
||||||
EngExec ENG1_EXEC:2;
|
EngExec ENG1_EXEC : 2;
|
||||||
bool CHIP_EN:1;
|
bool CHIP_EN : 1;
|
||||||
bool LOG_EN:1;
|
bool LOG_EN : 1;
|
||||||
} Reg00_Enable;
|
} Reg00_Enable;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EngModeDisable=0b00,
|
EngModeDisable = 0b00,
|
||||||
EngModeLoad=0b01,
|
EngModeLoad = 0b01,
|
||||||
EngModeRun=0b10,
|
EngModeRun = 0b10,
|
||||||
EngModeDirect=0b11,
|
EngModeDirect = 0b11,
|
||||||
} EngMode;
|
} EngMode;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
EngMode ENG3_MODE:2;
|
EngMode ENG3_MODE : 2;
|
||||||
EngMode ENG2_MODE:2;
|
EngMode ENG2_MODE : 2;
|
||||||
EngMode ENG1_MODE:2;
|
EngMode ENG1_MODE : 2;
|
||||||
uint8_t reserved:2;
|
uint8_t reserved : 2;
|
||||||
} Reg01_OpMode;
|
} Reg01_OpMode;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool INT_CLK_EN:1;
|
bool INT_CLK_EN : 1;
|
||||||
bool CLK_DET_EN:1;
|
bool CLK_DET_EN : 1;
|
||||||
uint8_t reserved0:3;
|
uint8_t reserved0 : 3;
|
||||||
bool PS_EN:1;
|
bool PS_EN : 1;
|
||||||
bool PWM_HF:1;
|
bool PWM_HF : 1;
|
||||||
uint8_t reserved1:1;
|
uint8_t reserved1 : 1;
|
||||||
} Reg08_Config;
|
} Reg08_Config;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t pc:3;
|
uint8_t pc : 3;
|
||||||
uint8_t reserved:5;
|
uint8_t reserved : 5;
|
||||||
} Reg09_Engine1PC;
|
} Reg09_Engine1PC;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t pc:3;
|
uint8_t pc : 3;
|
||||||
uint8_t reserved:5;
|
uint8_t reserved : 5;
|
||||||
} Reg0A_Engine2PC;
|
} Reg0A_Engine2PC;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t pc:3;
|
uint8_t pc : 3;
|
||||||
uint8_t reserved:5;
|
uint8_t reserved : 5;
|
||||||
} Reg0B_Engine3PC;
|
} Reg0B_Engine3PC;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool ENG3_INT:1;
|
bool ENG3_INT : 1;
|
||||||
bool ENG2_INT:1;
|
bool ENG2_INT : 1;
|
||||||
bool ENG1_INT:1;
|
bool ENG1_INT : 1;
|
||||||
bool EXT_CLK_USED:1;
|
bool EXT_CLK_USED : 1;
|
||||||
uint8_t reserved:5;
|
uint8_t reserved : 5;
|
||||||
} Reg0C_Status;
|
} Reg0C_Status;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -72,15 +73,15 @@ typedef struct {
|
|||||||
} Reg0D_Reset;
|
} Reg0D_Reset;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EngSelectI2C=0b00,
|
EngSelectI2C = 0b00,
|
||||||
EngSelectEngine1=0b01,
|
EngSelectEngine1 = 0b01,
|
||||||
EngSelectEngine2=0b10,
|
EngSelectEngine2 = 0b10,
|
||||||
EngSelectEngine3=0b11,
|
EngSelectEngine3 = 0b11,
|
||||||
} EngSelect;
|
} EngSelect;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
EngSelect blue:2;
|
EngSelect blue : 2;
|
||||||
EngSelect green:2;
|
EngSelect green : 2;
|
||||||
EngSelect red:2;
|
EngSelect red : 2;
|
||||||
EngSelect white:2;
|
EngSelect white : 2;
|
||||||
} Reg70_LedMap;
|
} Reg70_LedMap;
|
||||||
|
Loading…
Reference in New Issue
Block a user