mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-28 18:38:39 +00:00
feat(core): introduce stwlc38 driver
[no changelog]
This commit is contained in:
parent
b186c0d307
commit
962afee7fe
@ -19,6 +19,8 @@
|
||||
|
||||
#define NPM1300_I2C_INSTANCE 0
|
||||
|
||||
#define STWLC38_I2C_INSTANCE 1
|
||||
|
||||
#define I2C_COUNT 4
|
||||
|
||||
#define I2C_INSTANCE_0 I2C1
|
||||
|
430
core/embed/sys/powerctl/stwlc38/stwlc38.c
Normal file
430
core/embed/sys/powerctl/stwlc38/stwlc38.c
Normal file
@ -0,0 +1,430 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <trezor_bsp.h>
|
||||
#include <trezor_rtl.h>
|
||||
|
||||
#include <io/i2c_bus.h>
|
||||
#include <sys/irq.h>
|
||||
#include <sys/systimer.h>
|
||||
|
||||
#include "stwlc38.h"
|
||||
#include "stwlc38_defs.h"
|
||||
|
||||
#ifdef KERNEL_MODE
|
||||
|
||||
// !@# TODO: put following constants the board file
|
||||
#define STWLC38_INT_PIN GPIO_PIN_15
|
||||
#define STWLC38_INT_PORT GPIOG
|
||||
#define STWLC38_INT_PIN_CLK_ENA __HAL_RCC_GPIOG_CLK_ENABLE
|
||||
#define STWLC38_EXTI_INTERRUPT_GPIOSEL EXTI_GPIOG
|
||||
#define STWLC38_EXTI_INTERRUPT_LINE EXTI_LINE_15
|
||||
#define STWLC38_EXTI_INTERRUPT_NUM EXTI15_IRQn
|
||||
#define STWLC38_EXTI_INTERRUPT_HANDLER EXTI15_IRQHandler
|
||||
#define STWLC38_ENB_PIN GPIO_PIN_3
|
||||
#define STWLC37_ENB_PORT GPIOD
|
||||
#define STWLC38_ENB_PIN_CLK_ENA __HAL_RCC_GPIOD_CLK_ENABLE
|
||||
|
||||
// Period of the status readout [ms]
|
||||
#define STWLC38_STATUS_READOUT_INTERVAL_MS 500
|
||||
|
||||
// STWLC38 FSM states
|
||||
typedef enum {
|
||||
STWLC38_STATE_POWER_DOWN = 0,
|
||||
STWLC38_STATE_IDLE,
|
||||
STWLC38_STATE_VOUT_ENABLE,
|
||||
STWLC38_STATE_VOUT_DISABLE,
|
||||
STWLC38_STATE_STATUS_READOUT,
|
||||
} stwlc38_fsm_state_t;
|
||||
|
||||
typedef struct {
|
||||
// Rectified voltage [mV]
|
||||
uint16_t vrect;
|
||||
// Main LDO voltage output [mV]
|
||||
uint16_t vout;
|
||||
// Output current [mA]
|
||||
uint16_t icur;
|
||||
// Chip temperature [°C * 10]
|
||||
uint16_t tmeas;
|
||||
// Operating frequency [kHz]
|
||||
uint16_t opfreq;
|
||||
// NTC Temperature [°C * 10]
|
||||
uint16_t ntc;
|
||||
// RX Int Status 0
|
||||
uint8_t status0;
|
||||
|
||||
} stwlc38_status_regs_t;
|
||||
|
||||
// STWLC38 driver state
|
||||
typedef struct {
|
||||
// Set if the driver is initialized
|
||||
bool initialized;
|
||||
|
||||
// I2C bus where the STWLC38 is connected
|
||||
i2c_bus_t* i2c_bus;
|
||||
// Storage for the pending I2C packet
|
||||
i2c_packet_t pending_i2c_packet;
|
||||
// Status register (global buffer used for state readout)
|
||||
stwlc38_status_regs_t status_regs;
|
||||
// Timer used for periodic status readout
|
||||
systimer_t* timer;
|
||||
|
||||
// Main LDO output current state
|
||||
bool vout_enabled;
|
||||
// Main LDO output requested state
|
||||
bool vout_enabled_requested;
|
||||
// Flags set if status readout is scheduled
|
||||
bool status_readout_requested;
|
||||
|
||||
// Current status
|
||||
stwlc38_status_t status;
|
||||
// Current state of the FSM
|
||||
stwlc38_fsm_state_t state;
|
||||
|
||||
} stwlc38_driver_t;
|
||||
|
||||
// STWLC38 driver instance
|
||||
static stwlc38_driver_t g_stwlc38_driver = {
|
||||
.initialized = false,
|
||||
};
|
||||
|
||||
// forward declarations
|
||||
static void stwlc38_timer_callback(void* context);
|
||||
static void stwlc38_i2c_callback(void* context, i2c_packet_t* packet);
|
||||
static void stwlc38_fsm_continue(stwlc38_driver_t* drv);
|
||||
|
||||
void stwlc38_deinit(void) {
|
||||
stwlc38_driver_t* drv = &g_stwlc38_driver;
|
||||
|
||||
i2c_bus_close(drv->i2c_bus);
|
||||
systimer_delete(drv->timer);
|
||||
memset(drv, 0, sizeof(stwlc38_driver_t));
|
||||
}
|
||||
|
||||
bool stwlc38_init(void) {
|
||||
stwlc38_driver_t* drv = &g_stwlc38_driver;
|
||||
|
||||
if (drv->initialized) {
|
||||
return true;
|
||||
}
|
||||
|
||||
memset(drv, 0, sizeof(stwlc38_driver_t));
|
||||
|
||||
drv->state = STWLC38_STATE_POWER_DOWN;
|
||||
|
||||
// Main LDO output is enabled by default
|
||||
drv->vout_enabled = true;
|
||||
drv->vout_enabled_requested = true;
|
||||
|
||||
drv->i2c_bus = i2c_bus_open(STWLC38_I2C_INSTANCE);
|
||||
if (drv->i2c_bus == NULL) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
drv->timer = systimer_create(stwlc38_timer_callback, drv);
|
||||
if (drv->timer == NULL) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
STWLC38_INT_PIN_CLK_ENA();
|
||||
STWLC38_ENB_PIN_CLK_ENA();
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure = {0};
|
||||
|
||||
// INT pin, active low, external pull-up
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStructure.Pull = GPIO_PULLUP; // NOPULL;
|
||||
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStructure.Pin = STWLC38_INT_PIN;
|
||||
HAL_GPIO_Init(STWLC38_INT_PORT, &GPIO_InitStructure);
|
||||
|
||||
// ENB pin, active low, external pull-down
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStructure.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStructure.Pin = STWLC38_ENB_PIN;
|
||||
HAL_GPIO_WritePin(STWLC37_ENB_PORT, STWLC38_ENB_PIN, GPIO_PIN_RESET);
|
||||
HAL_GPIO_Init(STWLC37_ENB_PORT, &GPIO_InitStructure);
|
||||
|
||||
// Setup interrupt line for the STWLC38
|
||||
EXTI_HandleTypeDef EXTI_Handle = {0};
|
||||
EXTI_ConfigTypeDef EXTI_Config = {0};
|
||||
EXTI_Config.GPIOSel = STWLC38_EXTI_INTERRUPT_GPIOSEL;
|
||||
EXTI_Config.Line = STWLC38_EXTI_INTERRUPT_LINE;
|
||||
EXTI_Config.Mode = EXTI_MODE_INTERRUPT;
|
||||
EXTI_Config.Trigger = EXTI_TRIGGER_FALLING;
|
||||
HAL_EXTI_SetConfigLine(&EXTI_Handle, &EXTI_Config);
|
||||
NVIC_SetPriority(STWLC38_EXTI_INTERRUPT_NUM, IRQ_PRI_NORMAL);
|
||||
__HAL_GPIO_EXTI_CLEAR_FLAG(STWLC38_INT_PIN);
|
||||
NVIC_EnableIRQ(STWLC38_EXTI_INTERRUPT_NUM);
|
||||
|
||||
drv->initialized = true;
|
||||
|
||||
// Try to readout stwlc38 status, it may be already powered up
|
||||
irq_key_t irq_key = irq_lock();
|
||||
drv->status_readout_requested = true;
|
||||
stwlc38_fsm_continue(drv);
|
||||
irq_unlock(irq_key);
|
||||
|
||||
return true;
|
||||
|
||||
cleanup:
|
||||
stwlc38_deinit();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool stwlc38_enable(bool enable) {
|
||||
stwlc38_driver_t* drv = &g_stwlc38_driver;
|
||||
|
||||
if (!drv->initialized) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (enable) {
|
||||
HAL_GPIO_WritePin(STWLC37_ENB_PORT, STWLC38_ENB_PIN, GPIO_PIN_RESET);
|
||||
} else {
|
||||
HAL_GPIO_WritePin(STWLC37_ENB_PORT, STWLC38_ENB_PIN, GPIO_PIN_SET);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool stwlc38_enable_vout(bool enable) {
|
||||
stwlc38_driver_t* drv = &g_stwlc38_driver;
|
||||
|
||||
if (!drv->initialized) {
|
||||
return false;
|
||||
}
|
||||
|
||||
irq_key_t irq_key = irq_lock();
|
||||
|
||||
if (drv->vout_enabled_requested != enable) {
|
||||
drv->vout_enabled_requested = enable;
|
||||
stwlc38_fsm_continue(drv);
|
||||
}
|
||||
|
||||
irq_unlock(irq_key);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// I2C operation for writing 8-bit constant value to the STWLC38 register
|
||||
#define STWLC_WRITE_CONST8(reg, value) \
|
||||
{ \
|
||||
.flags = I2C_FLAG_TX | I2C_FLAG_EMBED | I2C_FLAG_START, .size = 3, \
|
||||
.data = {(reg) >> 8, (reg) & 0xFF, (value)}, \
|
||||
}
|
||||
|
||||
// I2C operations for reading 16-bit STWLC38 register into the
|
||||
// specified field in `g_stwlc38_driver` structure
|
||||
#define STWLC_READ_FIELD16(reg, field) \
|
||||
{ \
|
||||
.flags = I2C_FLAG_TX | I2C_FLAG_EMBED | I2C_FLAG_START, \
|
||||
.size = 2, \
|
||||
.data = {(reg) >> 8, (reg) & 0xFF}, \
|
||||
}, \
|
||||
{ \
|
||||
.flags = I2C_FLAG_RX, .size = 2, .ptr = &g_stwlc38_driver.field, \
|
||||
}
|
||||
|
||||
// I2C operations for reading 8-bit STWLC38 register into the
|
||||
// specified field in `g_stwlc38_driver` structure
|
||||
#define STWLC_READ_FIELD8(reg, field) \
|
||||
{ \
|
||||
.flags = I2C_FLAG_TX | I2C_FLAG_EMBED | I2C_FLAG_START, \
|
||||
.size = 2, \
|
||||
.data = {(reg) >> 8, (reg) & 0xFF}, \
|
||||
}, \
|
||||
{ \
|
||||
.flags = I2C_FLAG_RX, .size = 1, .ptr = &g_stwlc38_driver.field, \
|
||||
}
|
||||
|
||||
// I2C operations for readout of the current state into the
|
||||
// `g_stwlc38.state` structure
|
||||
static const i2c_op_t stwlc38_ops_status_readout[] = {
|
||||
STWLC_READ_FIELD16(STWLC38_REG_VRECT, status_regs.vrect),
|
||||
STWLC_READ_FIELD16(STWLC38_REG_VOUT, status_regs.vout),
|
||||
STWLC_READ_FIELD16(STWLC38_REG_ICUR, status_regs.icur),
|
||||
STWLC_READ_FIELD16(STWLC38_REG_TMEAS, status_regs.tmeas),
|
||||
STWLC_READ_FIELD16(STWLC38_REG_OPFREQ, status_regs.opfreq),
|
||||
STWLC_READ_FIELD16(STWLC38_REG_NTC, status_regs.ntc),
|
||||
STWLC_READ_FIELD8(STWLC38_REG_RXINT_STATUS0, status_regs.status0),
|
||||
};
|
||||
|
||||
// I2C operations for enabling of the main LDO
|
||||
static const i2c_op_t stwlc38_ops_vout_enable[] = {
|
||||
STWLC_WRITE_CONST8(STWLC38_RX_COMMAND, 0x01), // RX VOUT ON
|
||||
};
|
||||
|
||||
// I2C operations for disabling of the main LDO
|
||||
static const i2c_op_t stwlc38_ops_vout_disable[] = {
|
||||
STWLC_WRITE_CONST8(STWLC38_RX_COMMAND, 0x02), // RX VOUT OFF
|
||||
};
|
||||
|
||||
#define stwlc38_i2c_submit(drv, ops) \
|
||||
_stwlc38_i2c_submit(drv, ops, ARRAY_LENGTH(ops))
|
||||
|
||||
// helper function for submitting I2C operations
|
||||
static void _stwlc38_i2c_submit(stwlc38_driver_t* drv, const i2c_op_t* ops,
|
||||
size_t op_count) {
|
||||
i2c_packet_t* pkt = &drv->pending_i2c_packet;
|
||||
|
||||
memset(pkt, 0, sizeof(i2c_packet_t));
|
||||
pkt->address = STWLC38_I2C_ADDRESS;
|
||||
pkt->context = drv;
|
||||
pkt->callback = stwlc38_i2c_callback;
|
||||
pkt->timeout = 0;
|
||||
pkt->ops = (i2c_op_t*)ops;
|
||||
pkt->op_count = op_count;
|
||||
|
||||
i2c_status_t status = i2c_bus_submit(drv->i2c_bus, pkt);
|
||||
|
||||
if (status != I2C_STATUS_OK) {
|
||||
// This should never happen
|
||||
error_shutdown("STWLC38 I2C submit error");
|
||||
}
|
||||
}
|
||||
|
||||
bool stwlc38_get_status(stwlc38_status_t* status) {
|
||||
stwlc38_driver_t* drv = &g_stwlc38_driver;
|
||||
|
||||
if (!drv->initialized) {
|
||||
return false;
|
||||
}
|
||||
|
||||
irq_key_t irq_key = irq_lock();
|
||||
*status = drv->status;
|
||||
irq_unlock(irq_key);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void stwlc38_timer_callback(void* context) {
|
||||
stwlc38_driver_t* drv = (stwlc38_driver_t*)context;
|
||||
|
||||
// Schedule the status readout
|
||||
drv->status_readout_requested = true;
|
||||
stwlc38_fsm_continue(drv);
|
||||
}
|
||||
|
||||
static void stwlc38_i2c_callback(void* context, i2c_packet_t* packet) {
|
||||
stwlc38_driver_t* drv = (stwlc38_driver_t*)context;
|
||||
|
||||
if (packet->status != I2C_STATUS_OK) {
|
||||
memset(&drv->status, 0, sizeof(stwlc38_status_t));
|
||||
// Kill periodic timer
|
||||
systimer_unset(drv->timer);
|
||||
// !@# retry on error?????
|
||||
drv->state = STWLC38_STATE_POWER_DOWN;
|
||||
drv->status_readout_requested = false;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
switch (drv->state) {
|
||||
case STWLC38_STATE_STATUS_READOUT:
|
||||
drv->status_readout_requested = false;
|
||||
|
||||
bool was_ready = drv->status.ready;
|
||||
|
||||
// Status registers readout completed
|
||||
memset(&drv->status, 0, sizeof(stwlc38_status_t));
|
||||
drv->status.ready = true;
|
||||
drv->status.vout_ready = drv->status_regs.status0 & 0x40;
|
||||
drv->status.vrect = drv->status_regs.vrect;
|
||||
drv->status.vout = drv->status_regs.vout;
|
||||
drv->status.icur = drv->status_regs.icur;
|
||||
drv->status.tmeas = drv->status_regs.tmeas;
|
||||
drv->status.opfreq = drv->status_regs.opfreq;
|
||||
drv->status.ntc = drv->status_regs.ntc;
|
||||
|
||||
// Just powered-up ?
|
||||
if (!was_ready) {
|
||||
// After power-up, ensure that the main LDO is in the requested state
|
||||
drv->vout_enabled = !drv->vout_enabled_requested;
|
||||
// Start the periodic timer
|
||||
systimer_set_periodic(drv->timer, STWLC38_STATUS_READOUT_INTERVAL_MS);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case STWLC38_STATE_VOUT_ENABLE:
|
||||
// Main LDO output enabled
|
||||
drv->vout_enabled = true;
|
||||
break;
|
||||
|
||||
case STWLC38_STATE_VOUT_DISABLE:
|
||||
// Main LDO output disabled
|
||||
drv->vout_enabled = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
// This should never happen
|
||||
break;
|
||||
}
|
||||
|
||||
drv->state = STWLC38_STATE_IDLE;
|
||||
stwlc38_fsm_continue(drv);
|
||||
}
|
||||
|
||||
void STWLC38_EXTI_INTERRUPT_HANDLER(void) {
|
||||
stwlc38_driver_t* drv = &g_stwlc38_driver;
|
||||
|
||||
// Clear the EXTI line pending bit
|
||||
__HAL_GPIO_EXTI_CLEAR_FLAG(STWLC38_INT_PIN);
|
||||
|
||||
if (drv->state == STWLC38_STATE_POWER_DOWN) {
|
||||
// Inform the powerctl module about the WPC
|
||||
// wakeup_flags_set(WAKEUP_FLAGS_WPC);
|
||||
drv->status_readout_requested = true;
|
||||
stwlc38_fsm_continue(drv);
|
||||
}
|
||||
}
|
||||
|
||||
static void stwlc38_fsm_continue(stwlc38_driver_t* drv) {
|
||||
// The order of the following conditions defines the priority
|
||||
|
||||
if (drv->state == STWLC38_STATE_POWER_DOWN && drv->status_readout_requested) {
|
||||
// Check if the i2c interface is ready
|
||||
stwlc38_i2c_submit(drv, stwlc38_ops_status_readout);
|
||||
drv->state = STWLC38_STATE_STATUS_READOUT;
|
||||
return;
|
||||
}
|
||||
|
||||
if (drv->state != STWLC38_STATE_IDLE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (drv->vout_enabled != drv->vout_enabled_requested) {
|
||||
// Enable/Disable the main LDO output
|
||||
if (drv->vout_enabled_requested) {
|
||||
stwlc38_i2c_submit(drv, stwlc38_ops_vout_enable);
|
||||
drv->state = STWLC38_STATE_VOUT_ENABLE;
|
||||
} else {
|
||||
stwlc38_i2c_submit(drv, stwlc38_ops_vout_disable);
|
||||
drv->state = STWLC38_STATE_VOUT_DISABLE;
|
||||
}
|
||||
} else if (drv->status_readout_requested) {
|
||||
// Read status registers
|
||||
stwlc38_i2c_submit(drv, stwlc38_ops_status_readout);
|
||||
drv->state = STWLC38_STATE_STATUS_READOUT;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // KERNEL_MODE
|
73
core/embed/sys/powerctl/stwlc38/stwlc38.h
Normal file
73
core/embed/sys/powerctl/stwlc38/stwlc38.h
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TREZORHAL_STWLC38_H
|
||||
#define TREZORHAL_STWLC38_H
|
||||
|
||||
#include <trezor_types.h>
|
||||
|
||||
// Initializes STWLC38 driver
|
||||
//
|
||||
// After initialization, the STWLC38 is enabled by default.
|
||||
bool stwlc38_init(void);
|
||||
|
||||
// Deinitializes STWLC38 driver
|
||||
void stwlc38_deinit(void);
|
||||
|
||||
// Enables or disables the STWLC38. This can be used to enable/disable
|
||||
// wireless charging functionality.
|
||||
//
|
||||
// If the STWLC38 is disabled, it's not self-powered and is unable to
|
||||
// communicate over I2C. STWLC38 is disabled by default after initialization.
|
||||
//
|
||||
// Returns true if the STWLC38 was successfully enabled or disabled.
|
||||
bool stwlc38_enable(bool enable);
|
||||
|
||||
// Enables or disables the main LDO output.
|
||||
//
|
||||
// Main LDO output is enabled by default after initialization.
|
||||
//
|
||||
// Returns true if the main LDO output was successfully enabled or disabled.
|
||||
bool stwlc38_enable_vout(bool enable);
|
||||
|
||||
typedef struct {
|
||||
// Powered-up and initialized
|
||||
bool ready;
|
||||
// Providing power to the system
|
||||
bool vout_ready;
|
||||
|
||||
// Rectified voltage [mV]
|
||||
uint16_t vrect;
|
||||
// Main LDO voltage output [mV]
|
||||
uint16_t vout;
|
||||
// Output current [mA]
|
||||
uint16_t icur;
|
||||
// Chip temperature [°C * 10]
|
||||
uint16_t tmeas;
|
||||
// Operating frequency [kHz]
|
||||
uint16_t opfreq;
|
||||
// NTC Temperature [°C * 10]
|
||||
uint16_t ntc;
|
||||
|
||||
} stwlc38_status_t;
|
||||
|
||||
// Gets the current state of the STWLC38
|
||||
bool stwlc38_get_status(stwlc38_status_t* status);
|
||||
|
||||
#endif // TREZORHAL_STWLC38_H
|
47
core/embed/sys/powerctl/stwlc38/stwlc38_defs.h
Normal file
47
core/embed/sys/powerctl/stwlc38/stwlc38_defs.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TREZORHAL_STWLC38_DEFS_H
|
||||
#define TREZORHAL_STWLC38_DEFS_H
|
||||
|
||||
// I2C address of the STWLC38 on the I2C bus.
|
||||
#define STWLC38_I2C_ADDRESS 0x61
|
||||
|
||||
// RX Command register
|
||||
#define STWLC38_RX_COMMAND 0x90
|
||||
|
||||
// Rectified voltage [mV/16-bit]
|
||||
#define STWLC38_REG_VRECT 0x92
|
||||
// Main LDO voltage output [mV/16-bit]
|
||||
#define STWLC38_REG_VOUT 0x94
|
||||
// Output current [mA]
|
||||
#define STWLC38_REG_ICUR 0x96
|
||||
// Chip temperature [°C * 10]
|
||||
#define STWLC38_REG_TMEAS 0x98
|
||||
// Operating frequency [kHz]
|
||||
#define STWLC38_REG_OPFREQ 0x9A
|
||||
// NTC Temperature [°C * 10]
|
||||
#define STWLC38_REG_NTC 0x9C
|
||||
|
||||
// 3-byte status register
|
||||
#define STWLC38_REG_RXINT_STATUS0 0x8C
|
||||
#define STWLC38_REG_RXINT_STATUS1 0x8D
|
||||
#define STWLC38_REG_RXINT_STATUS2 0x8E
|
||||
|
||||
#endif // TREZORHAL_STWLC38_DEFS_H
|
@ -117,7 +117,10 @@ def configure(
|
||||
"USE_RESET_TO_BOOT=1",
|
||||
]
|
||||
|
||||
sources += ["embed/sys/powerctl/npm1300/npm1300.c"]
|
||||
sources += [
|
||||
"embed/sys/powerctl/npm1300/npm1300.c",
|
||||
"embed/sys/powerctl/stwlc38/stwlc38.c"
|
||||
]
|
||||
|
||||
env.get("ENV")["LINKER_SCRIPT"] = linker_script
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user