Skip to content

Commit efac3bb

Browse files
author
Gavan Fantom
committed
Battery meter, save settings, set default file, beep options
Also some refactoring of the way we select files along the way. Now you can set a default file. This won't be stable across adding or removing files, but you can always set the default file again. The beep setting now does something. The battery meter setting now does something too. Saving the settings now does something, and the settings are loaded at startup. The .settings file is still shown in the file menu so that it can be deleted.
1 parent 7e912ca commit efac3bb

File tree

11 files changed

+287
-119
lines changed

11 files changed

+287
-119
lines changed

Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ DEVICE ?= /dev/ttyUSB0
55
SRCS = hello.c startup_ARMCM0.S system.c display.c font.c i2c.c speaker.c
66
SRCS += spi.c spiflash.c uart.c write.c zmodem.c crc.c timer.c cli.c
77
SRCS += lock.c fault.c button.c file.c frame.c fs.c menu.c settings.c
8+
SRCS += battery.c
89
LITTLEFS = littlefs
910
LITTLEFS_SRCS = lfs.c lfs_util.c
1011
LIBDIR = lpc/src

battery.c

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/* battery.c */
2+
3+
#include "hello.h"
4+
#include "battery.h"
5+
#include "timer.h"
6+
7+
void battery_read_enable(bool on);
8+
9+
#define ADC_CR (ADC_CR_CH_SEL(1) | ADC_CR_CLKDIV(11))
10+
#define BATTERY_COUNT 2
11+
#define BATTERY_INTERVAL 1000
12+
13+
int battery_counter;
14+
int battery_reading;
15+
16+
void battery_init(void)
17+
{
18+
battery_counter = BATTERY_COUNT;
19+
LPC_IOCON->REG[IOCON_PIO1_0] = IOCON_FUNC2;
20+
LPC_IOCON->REG[IOCON_PIO1_1] = IOCON_FUNC1 | IOCON_ADMODE_EN;
21+
LPC_GPIO1->DIR |= (1<<1); // output
22+
battery_read_enable(false);
23+
LPC_SYSCTL->PDRUNCFG &= ~0x10; // Enable power to ADC
24+
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_ADC);
25+
Chip_SYSCTL_DeassertPeriphReset(RESET_ADC0);
26+
LPC_ADC->CR = ADC_CR;
27+
LPC_ADC->INTEN = 1<<1;
28+
NVIC_EnableIRQ(ADC_IRQn);
29+
}
30+
31+
void battery_read_enable(bool on)
32+
{
33+
if (on)
34+
LPC_GPIO1->DATA[DATAREG] |= (1<<1);
35+
else
36+
LPC_GPIO1->DATA[DATAREG] &= ~(1<<1);
37+
}
38+
39+
void ADC_IRQHandler(void)
40+
{
41+
LPC_ADC->CR = ADC_CR;
42+
int data = LPC_ADC->DR[1];
43+
battery_reading = data & 0xffff;
44+
battery_read_enable(false);
45+
}
46+
47+
void battery_read(void)
48+
{
49+
LPC_ADC->CR = ADC_CR | ADC_CR_START_NOW;
50+
}
51+
52+
void battery_poll(void)
53+
{
54+
uint32_t time = systime_timer_get();
55+
static uint32_t last_time = 0;
56+
if ((time - last_time) >= BATTERY_INTERVAL) {
57+
last_time = time;
58+
battery_timer();
59+
}
60+
if (battery_counter) {
61+
if (--battery_counter == 0)
62+
battery_read();
63+
}
64+
}
65+
66+
void battery_timer(void)
67+
{
68+
battery_read_enable(true);
69+
battery_counter = BATTERY_COUNT;
70+
}
71+
72+
int battery_status(void)
73+
{
74+
return battery_reading;
75+
}

battery.h

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/* battery.h */
2+
3+
#ifndef BATTERY_H
4+
#define BATTERY_H
5+
6+
void battery_init(void);
7+
void battery_poll(void);
8+
void battery_timer(void);
9+
int battery_status(void);
10+
11+
#define BATTERY_VREF 3300
12+
#define BATTERY_FULLSCALE (BATTERY_VREF * 2)
13+
#define BATTERY_RANGE 0xffc0
14+
#define BATTERY_VALUE(x) ((x) * BATTERY_FULLSCALE / BATTERY_RANGE)
15+
16+
#define BATTERY_EMPTY BATTERY_VALUE(3000)
17+
#define BATTERY_THRESHOLD BATTERY_VALUE(3300)
18+
#define BATTERY_FULL BATTERY_VALUE(4100)
19+
20+
#endif /* BATTERY_H */

file.c

+70-61
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@
77
#include "frame.h"
88
#include <string.h>
99
#include "menu.h"
10-
11-
#define FIRST_FILE 2
10+
#include "settings.h"
1211

1312
bool file_open;
1413
struct filedata filedata;
@@ -17,7 +16,7 @@ bool safe_start;
1716

1817
void file_init(bool safe)
1918
{
20-
dir_offset = FIRST_FILE;
19+
dir_offset = settings_default_file();
2120
file_open = false;
2221
safe_start = safe;
2322
start_display();
@@ -134,60 +133,69 @@ void file_load(const char *filename)
134133
stop_display();
135134
}
136135

137-
int load_file_by_offset(int target)
136+
char *file_read_dirent(lfs_dir_t *dir, struct lfs_info *info, bool ignore_dot)
138137
{
139-
lfs_dir_t dir;
140-
if (safe_start)
141-
return 0;
142-
if (file_open)
143-
stop_display();
144-
int err = lfs_dir_open(&fs_lfs, &dir, "/");
145-
if (err) {
146-
return -1;
147-
}
148-
struct lfs_info info;
149-
int last_fileno = 0;
150-
int fileno;
151-
for (fileno = 0; true; fileno++) {
152-
int res = lfs_dir_read(&fs_lfs, &dir, &info);
153-
if (res < 0) {
154-
lfs_dir_close(&fs_lfs, &dir);
155-
return res;
156-
}
157-
if (res == 0) {
158-
if (target == FIRST_FILE) {
159-
lfs_dir_close(&fs_lfs, &dir);
160-
return 0;
161-
}
162-
fileno = -1; // This will be incremented on continue
163-
if (target < 0) {
164-
target = last_fileno;
165-
} else {
166-
target = FIRST_FILE;
167-
}
168-
lfs_dir_rewind(&fs_lfs, &dir);
138+
while (1) {
139+
int res = lfs_dir_read(&fs_lfs, dir, info);
140+
if (res != 1)
141+
return NULL;
142+
if (info->type != LFS_TYPE_REG)
169143
continue;
170-
}
171-
172-
if (fileno < target)
144+
if (ignore_dot && (info->name[0] == '.'))
173145
continue;
146+
return info->name;
147+
}
148+
}
174149

175-
last_fileno = fileno;
150+
char *file_find(lfs_dir_t *dir, struct lfs_info *info, int fileno, bool ignore_dot)
151+
{
152+
char *name = NULL;
153+
if (lfs_dir_open(&fs_lfs, dir, "/"))
154+
return NULL;
155+
for (int i = 0; i <= fileno; i++) {
156+
name = file_read_dirent(dir, info, ignore_dot);
157+
if (!name)
158+
break;
159+
}
160+
lfs_dir_close(&fs_lfs, dir);
161+
return name;
162+
}
176163

177-
if (fileno == target) {
178-
if (info.type != LFS_TYPE_REG) {
179-
target++;
180-
continue;
181-
}
164+
int file_count(bool ignore_dot)
165+
{
166+
lfs_dir_t dir;
167+
struct lfs_info info;
168+
int count = 0;
169+
if (lfs_dir_open(&fs_lfs, &dir, "/"))
170+
return 0;
171+
while (file_read_dirent(&dir, &info, ignore_dot))
172+
count++;
173+
lfs_dir_close(&fs_lfs, &dir);
174+
return count;
175+
}
182176

183-
lfs_dir_close(&fs_lfs, &dir);
184-
file_load(info.name);
185-
return fileno;
186-
}
177+
int load_file_by_offset(int target)
178+
{
179+
lfs_dir_t dir;
180+
struct lfs_info info;
181+
char *name = file_find(&dir, &info, target, true);
182+
if (name) {
183+
file_load(name);
184+
return target;
187185
}
186+
if (target < 0)
187+
target = file_count(true) - 1;
188+
else
189+
target = 0;
190+
name = file_find(&dir, &info, target, true);
191+
if (name) {
192+
file_load(name);
193+
return target;
194+
}
195+
return 0;
188196
}
189197

190-
void file_load_update_offset(const char *filename)
198+
void file_update_offset(const char *filename)
191199
{
192200
lfs_dir_t dir;
193201
if (file_open)
@@ -197,38 +205,39 @@ void file_load_update_offset(const char *filename)
197205
struct lfs_info info;
198206
int fileno;
199207
for (fileno = 0; true; fileno++) {
200-
int res = lfs_dir_read(&fs_lfs, &dir, &info);
201-
if (res < 0) {
202-
lfs_dir_close(&fs_lfs, &dir);
208+
char *name = file_read_dirent(&dir, &info, true);
209+
if (!name)
203210
break;
204-
}
205-
if (info.type != LFS_TYPE_REG)
206-
continue;
207211

208-
if (strcmp(info.name, filename) == 0) {
212+
if (strcmp(name, filename) == 0) {
209213
dir_offset = fileno;
210214
break;
211215
}
212216
}
213217

214218
lfs_dir_close(&fs_lfs, &dir);
219+
}
215220

221+
void file_load_update_offset(const char *filename)
222+
{
223+
file_update_offset(filename);
216224
file_load(filename);
217225
}
218226

227+
void file_set_default(const char *filename)
228+
{
229+
file_update_offset(filename);
230+
settings_set_default_file(dir_offset);
231+
}
232+
219233
void next_file(void)
220234
{
221235
dir_offset = load_file_by_offset(dir_offset + 1);
222236
}
223237

224238
void prev_file(void)
225239
{
226-
dir_offset--;
227-
if (dir_offset < FIRST_FILE)
228-
dir_offset = -1;
229-
int res = load_file_by_offset(dir_offset);
230-
if (dir_offset < FIRST_FILE)
231-
dir_offset = res;
240+
dir_offset = load_file_by_offset(dir_offset - 1);
232241
}
233242

234243
void start_display(void)

file.h

+7
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#ifndef FILE_H
44
#define FILE_H
55

6+
#include "lfs.h"
7+
68
extern bool file_open;
79
extern bool safe_start;
810

@@ -77,4 +79,9 @@ int load_file_by_offset(int target);
7779
void next_file(void);
7880
void prev_file(void);
7981

82+
char *file_read_dirent(lfs_dir_t *dir, struct lfs_info *info, bool ignore_dot);
83+
char *file_find(lfs_dir_t *dir, struct lfs_info *info, int fileno, bool ignore_dot);
84+
int file_count(bool ignore_dot);
85+
void file_set_default(const char *filename);
86+
8087
#endif /* FILE_H */

frame.c

+37
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "lock.h"
1414
#include "menu.h"
1515
#include "settings.h"
16+
#include "battery.h"
1617

1718
uint8_t frame1[1024];
1819
uint8_t frame2[1024];
@@ -227,6 +228,40 @@ void draw_video(uint8_t *frame)
227228
return;
228229
}
229230

231+
#define BATTERY_PIXELS 20
232+
#define BATTERY_WIDTH (BATTERY_PIXELS + 6)
233+
234+
void draw_battery(uint8_t *frame)
235+
{
236+
int battery = battery_status();
237+
if (battery < BATTERY_EMPTY)
238+
battery = BATTERY_EMPTY;
239+
if (battery > BATTERY_FULL)
240+
battery = BATTERY_FULL;
241+
battery = battery - BATTERY_EMPTY;
242+
battery = battery * BATTERY_PIXELS / (BATTERY_FULL - BATTERY_EMPTY);
243+
int settings = settings_battery();
244+
if (settings == BATTERY_OFF)
245+
return;
246+
if (settings == BATTERY_WHENLOW)
247+
if (battery < BATTERY_THRESHOLD)
248+
return;
249+
int offset = 128 - BATTERY_WIDTH;
250+
frame[offset++] = 0x3c;
251+
frame[offset++] = 0x24;
252+
frame[offset++] = 0xe7;
253+
frame[offset++] = 0x81;
254+
for (int i = 0; i < BATTERY_PIXELS; i++) {
255+
if (i < (BATTERY_PIXELS - battery))
256+
frame[offset + i] = 0x81;
257+
else
258+
frame[offset + i] = 0xbd;
259+
}
260+
offset += BATTERY_PIXELS;
261+
frame[offset++] = 0x81;
262+
frame[offset++] = 0xff;
263+
}
264+
230265
void FRAME_HANDLER(void)
231266
{
232267
static int contrast = 0;
@@ -268,6 +303,8 @@ void frame_update(void)
268303
} else {
269304
draw_error(screen_buf);
270305
}
306+
draw_battery(screen_buf);
307+
battery_poll();
271308

272309
display_buf = screen_buf;
273310
screen_buf = (screen_buf == frame1)?frame2:frame1;

0 commit comments

Comments
 (0)