Skip to content

Commit 64e9c2c

Browse files
committed
drv/battery_adc: Add support for Li-ion batteries
This allow use of Li-ion batteries in the Technic hub (even though there isn't an official battery pack from LEGO). This also fixes low battery shutdown on Prime hub. Issue: pybricks/pybricks-micropython#5
1 parent b6548a3 commit 64e9c2c

File tree

11 files changed

+138
-8
lines changed

11 files changed

+138
-8
lines changed

lib/pbio/drv/battery/battery_adc.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@
2828
// PBDRV_CONFIG_BATTERY_ADC_CURRENT_SCALED_MAX:
2929
// The current in mA that corresponds that would result in the raw measured
3030
// value PBDRV_CONFIG_BATTERY_ADC_CURRENT_RAW_MAX being read on the ADC.
31+
// PBDRV_CONFIG_BATTERY_ADC_TYPE:
32+
// 1 = PBDRV_BATTERY_TYPE_ALKALINE only
33+
// 2 = PBDRV_BATTERY_TYPE_LIION only
34+
// 3 = type indicated by GPIO button
3135

3236
#include <pbdrv/config.h>
3337

@@ -38,9 +42,23 @@
3842
#include <contiki.h>
3943

4044
#include <pbdrv/adc.h>
45+
#include <pbdrv/battery.h>
46+
#include <pbdrv/gpio.h>
4147
#include <pbio/error.h>
4248

49+
#include "battery_adc.h"
50+
51+
#if PBDRV_CONFIG_BATTERY_ADC_TYPE == 3
52+
static pbdrv_battery_type_t pbdrv_battery_type;
53+
#endif
54+
4355
void pbdrv_battery_init() {
56+
#if PBDRV_CONFIG_BATTERY_ADC_TYPE == 3
57+
const pbdrv_battery_adc_platform_data_t *pdata = &pbdrv_battery_adc_platform_data;
58+
pbdrv_gpio_set_pull(&pdata->gpio, pdata->pull);
59+
pbdrv_battery_type = pbdrv_gpio_input(&pdata->gpio) ?
60+
PBDRV_BATTERY_TYPE_ALKALINE : PBDRV_BATTERY_TYPE_LIION;
61+
#endif
4462
}
4563

4664
pbio_error_t pbdrv_battery_get_current_now(uint16_t *value) {
@@ -104,4 +122,16 @@ pbio_error_t pbdrv_battery_get_voltage_now(uint16_t *value) {
104122
return PBIO_SUCCESS;
105123
}
106124

125+
pbdrv_battery_type_t pbdrv_battery_get_type() {
126+
#if PBDRV_CONFIG_BATTERY_ADC_TYPE == 1
127+
return PBDRV_BATTERY_TYPE_ALKALINE;
128+
#elif PBDRV_CONFIG_BATTERY_ADC_TYPE == 2
129+
return PBDRV_BATTERY_TYPE_LIION;
130+
#elif PBDRV_CONFIG_BATTERY_ADC_TYPE == 3
131+
return pbdrv_battery_type;
132+
#else
133+
#error "Bad PBDRV_CONFIG_BATTERY_ADC_TYPE value"
134+
#endif
135+
}
136+
107137
#endif // PBDRV_CONFIG_BATTERY_ADC

lib/pbio/drv/battery/battery_adc.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// SPDX-License-Identifier: MIT
2+
// Copyright (c) 2020 The Pybricks Authors
3+
4+
#ifndef _PBDRV_BATTERY_ADC_H_
5+
#define _PBDRV_BATTERY_ADC_H_
6+
7+
#include <pbdrv/gpio.h>
8+
9+
// NOTE: Currently platform data is only needed for this driver when
10+
// PBDRV_CONFIG_BATTERY_ADC_TYPE == 3
11+
12+
/**
13+
* Platform data for ADC battery device.
14+
*/
15+
typedef struct {
16+
/** Battery type detection GPIO. */
17+
pbdrv_gpio_t gpio;
18+
/** Battery type detection GPIO pull setting. */
19+
pbdrv_gpio_pull_t pull;
20+
} pbdrv_battery_adc_platform_data_t;
21+
22+
// defined in platform.c
23+
const pbdrv_battery_adc_platform_data_t pbdrv_battery_adc_platform_data;
24+
25+
#endif // _PBDRV_BATTERY_ADC_H_

lib/pbio/drv/battery/battery_nxt.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@
1313
#include <contiki.h>
1414
#include <nxt/nxt_avr.h>
1515

16+
#include <pbdrv/battery.h>
1617
#include <pbio/error.h>
1718

1819
void pbdrv_battery_init() {
1920
}
2021

2122
pbio_error_t pbdrv_battery_get_voltage_now(uint16_t *value) {
23+
// Battery voltage includes bit 0x8000 to indicate rechargeable battery
2224
*value = battery_voltage() & 0x7FFF;
2325
return PBIO_SUCCESS;
2426
}
@@ -28,4 +30,10 @@ pbio_error_t pbdrv_battery_get_current_now(uint16_t *value) {
2830
return PBIO_ERROR_NOT_SUPPORTED;
2931
}
3032

33+
pbdrv_battery_type_t pbdrv_battery_get_type() {
34+
// Battery voltage includes bit 0x8000 to indicate rechargeable battery
35+
return (battery_voltage() & 0x8000) ? PBDRV_BATTERY_TYPE_LIION
36+
: PBDRV_BATTERY_TYPE_ALKALINE;
37+
}
38+
3139
#endif // PBDRV_CONFIG_BATTERY_NXT

lib/pbio/include/pbdrv/battery.h

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,17 @@
1414
#include <pbdrv/config.h>
1515
#include <pbio/error.h>
1616

17-
#if PBDRV_CONFIG_BATTERY
17+
/** Battery chemistry types. */
18+
typedef enum {
19+
/** The battery type is not known. */
20+
PBDRV_BATTERY_TYPE_UNKNOWN,
21+
/** The batteries are alkaline (e.g. AA/AAA). */
22+
PBDRV_BATTERY_TYPE_ALKALINE,
23+
/** The batteries are Li-ion. */
24+
PBDRV_BATTERY_TYPE_LIION,
25+
} pbdrv_battery_type_t;
1826

27+
#if PBDRV_CONFIG_BATTERY
1928

2029
/** @cond INTERNAL */
2130
void pbdrv_battery_init();
@@ -39,6 +48,12 @@ pbio_error_t pbdrv_battery_get_voltage_now(uint16_t *value);
3948
*/
4049
pbio_error_t pbdrv_battery_get_current_now(uint16_t *value);
4150

51+
/**
52+
* Gets the battery chemistry type.
53+
* @return The type of battery.
54+
*/
55+
pbdrv_battery_type_t pbdrv_battery_get_type();
56+
4257
#else // PBDRV_CONFIG_BATTERY
4358

4459
#define pbdrv_battery_init()
@@ -53,6 +68,10 @@ static inline pbio_error_t pbdrv_battery_get_current_now(uint16_t *value) {
5368
return PBIO_ERROR_NOT_SUPPORTED;
5469
}
5570

71+
static inline pbdrv_battery_type_t pbdrv_battery_get_type() {
72+
return PBDRV_BATTERY_TYPE_UNKNOWN;
73+
}
74+
5675
#endif // PBDRV_CONFIG_BATTERY
5776

5877
#endif // _PBDRV_BATTERY_H_

lib/pbio/platform/city_hub/pbdrvconfig.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#define PBDRV_CONFIG_BATTERY_ADC_CURRENT_RAW_OFFSET 130
2020
#define PBDRV_CONFIG_BATTERY_ADC_CURRENT_RAW_MAX 4096
2121
#define PBDRV_CONFIG_BATTERY_ADC_CURRENT_SCALED_MAX 2448
22+
#define PBDRV_CONFIG_BATTERY_ADC_TYPE (1)
2223

2324
#define PBDRV_CONFIG_BUTTON (1)
2425
#define PBDRV_CONFIG_BUTTON_GPIO (1)

lib/pbio/platform/move_hub/pbdrvconfig.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#define PBDRV_CONFIG_BATTERY_ADC_CURRENT_RAW_OFFSET 0
2020
#define PBDRV_CONFIG_BATTERY_ADC_CURRENT_RAW_MAX 4096
2121
#define PBDRV_CONFIG_BATTERY_ADC_CURRENT_SCALED_MAX 2448
22+
#define PBDRV_CONFIG_BATTERY_ADC_TYPE (1)
2223

2324
#define PBDRV_CONFIG_BLUETOOTH (1)
2425

lib/pbio/platform/prime_hub/pbdrvconfig.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#define PBDRV_CONFIG_BATTERY_ADC_CURRENT_RAW_OFFSET 0
2727
#define PBDRV_CONFIG_BATTERY_ADC_CURRENT_RAW_MAX 4096
2828
#define PBDRV_CONFIG_BATTERY_ADC_CURRENT_SCALED_MAX 7300
29+
#define PBDRV_CONFIG_BATTERY_ADC_TYPE (2)
2930

3031
#define PBDRV_CONFIG_BUTTON (1)
3132
#define PBDRV_CONFIG_BUTTON_ADC (1)

lib/pbio/platform/prime_hub/sys.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
#include "pbio/event.h"
99
#include "pbio/main.h"
1010

11+
#include <pbsys/battery.h>
1112
#include <pbsys/status.h>
13+
#include <pbsys/supervisor.h>
1214
#include <pbsys/sys.h>
1315

1416
#include "../sys/hmi.h"
@@ -43,6 +45,7 @@ PROCESS_THREAD(pbsys_process, ev, data) {
4345

4446
PROCESS_BEGIN();
4547

48+
pbsys_battery_init();
4649
pbsys_hmi_init();
4750
etimer_set(&timer, clock_from_msec(50));
4851

@@ -51,7 +54,9 @@ PROCESS_THREAD(pbsys_process, ev, data) {
5154
pbsys_hmi_handle_event(ev, data);
5255
if (ev == PROCESS_EVENT_TIMER && etimer_expired(&timer)) {
5356
etimer_reset(&timer);
57+
pbsys_battery_poll();
5458
pbsys_hmi_poll();
59+
pbsys_supervisor_poll();
5560
} else if (ev == PBIO_EVENT_STATUS_SET) {
5661
if ((pbsys_status_t)data == PBSYS_STATUS_POWER_BUTTON_PRESSED && user_stop_func) {
5762
user_stop_func();

lib/pbio/platform/technic_hub/pbdrvconfig.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#define PBDRV_CONFIG_BATTERY_ADC_CURRENT_RAW_OFFSET 20
2525
#define PBDRV_CONFIG_BATTERY_ADC_CURRENT_RAW_MAX 4096
2626
#define PBDRV_CONFIG_BATTERY_ADC_CURRENT_SCALED_MAX 4178
27+
#define PBDRV_CONFIG_BATTERY_ADC_TYPE (3)
2728

2829
#define PBDRV_CONFIG_BLUETOOTH (1)
2930

lib/pbio/platform/technic_hub/platform.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "pbio/uartdev.h"
77

88
#include "../../drv/adc/adc_stm32_hal.h"
9+
#include "../../drv/battery/battery_adc.h"
910
#include "../../drv/button/button_gpio.h"
1011
#include "../../drv/ioport/ioport_lpf2.h"
1112
#include "../../drv/led/led_pwm.h"
@@ -42,6 +43,15 @@ enum {
4243

4344
// PBIO driver data
4445

46+
// Battery
47+
48+
const pbdrv_battery_adc_platform_data_t pbdrv_battery_adc_platform_data = {
49+
.gpio = { .bank = GPIOA, .pin = 12 },
50+
.pull = PBDRV_GPIO_PULL_NONE,
51+
};
52+
53+
// Button
54+
4555
const pbdrv_button_gpio_platform_t pbdrv_button_gpio_platform[PBDRV_CONFIG_BUTTON_GPIO_NUM_BUTTON] = {
4656
[0] = {
4757
.gpio = { .bank = GPIOC, .pin = 14 },

0 commit comments

Comments
 (0)