Skip to content

Commit b25d62d

Browse files
authored
Merge pull request #31 from kienvo/ble-save
feat: Save received data from BLE to flash
2 parents a6c6229 + 86e6f0d commit b25d62d

File tree

6 files changed

+181
-35
lines changed

6 files changed

+181
-35
lines changed

Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ src/ble/profile/legacy.c \
5757
src/ble/profile/devinfo.c \
5858
src/ble/setup.c \
5959
src/ble/peripheral.c \
60+
src/data.c \
6061

6162

6263
# ASM sources

src/ble/profile/legacy.c

+33-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
#include "utils.h"
22

3+
#include "../../data.h"
4+
#include "../../power.h"
5+
#include "../../leddrv.h"
6+
37
static const uint16_t ServiceUUID = 0xFEE0;
48
static const gattAttrType_t service = {2, (uint8_t *)&ServiceUUID};
59

@@ -16,7 +20,35 @@ static gattAttribute_t attr_table[] = {
1620

1721
static bStatus_t receive(uint8_t *val, uint16_t len)
1822
{
19-
/* TODO: implement data receiving here*/
23+
static uint16_t c, data_len, n;
24+
static uint8_t *data;
25+
if (len != LEGACY_TRANSFER_WIDTH) {
26+
return ATT_ERR_INVALID_VALUE_SIZE;
27+
}
28+
if (c == 0) {
29+
if (memcmp(val, "wang\0\0", 6)) {
30+
return ATT_ERR_INVALID_VALUE;
31+
} else {
32+
data = malloc(sizeof(data_legacy_t));
33+
}
34+
}
35+
36+
memcpy(data + c * len, val, len);
37+
38+
if (c == 1) {
39+
data_legacy_t *d = (data_legacy_t *)data;
40+
n = bigendian16_sum(d->sizes, 8);
41+
data_len = LEGACY_HEADER_SIZE + LED_ROWS * n;
42+
data = realloc(data, data_len);
43+
}
44+
45+
if (c > 2 && ((c+1) * LEGACY_TRANSFER_WIDTH) >= data_len) {
46+
data_flatSave(data, data_len);
47+
reset_jump();
48+
}
49+
50+
c++;
51+
return SUCCESS;
2052
}
2153

2254
static bStatus_t write_handler(uint16 connHandle, gattAttribute_t *pAttr,

src/data.c

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#include <stddef.h>
2+
#include <stdint.h>
3+
#include <stdlib.h>
4+
5+
#include "ISP583.h"
6+
7+
#include "data.h"
8+
#include "leddrv.h"
9+
10+
uint32_t bigendian16_sum(uint16_t *s, int len)
11+
{
12+
uint32_t sum = 0;
13+
while (len-- > 0) {
14+
sum += bswap16(s[len]);
15+
}
16+
return sum;
17+
}
18+
19+
uint32_t data_flatSave(uint8_t *data, uint32_t len)
20+
{
21+
uint32_t r = EEPROM_ERASE(0, len);
22+
if (r)
23+
return r;
24+
return EEPROM_WRITE(0, data, len);
25+
}
26+
27+
uint16_t data_flash2newmem(uint8_t **chunk, uint32_t n)
28+
{
29+
data_legacy_t header;
30+
EEPROM_READ(0, &header, LEGACY_HEADER_SIZE);
31+
32+
uint16_t size = bswap16(header.sizes[n]) * LED_ROWS;
33+
if (size == 0)
34+
return 0;
35+
36+
uint16_t offs = LEGACY_HEADER_SIZE
37+
+ bigendian16_sum(header.sizes, n) * LED_ROWS;
38+
39+
*chunk = malloc(size);
40+
EEPROM_READ(offs, *chunk, size);
41+
return size;
42+
}
43+
44+
static void __chunk2buffer(uint16_t *fb, uint8_t *chunk, int col)
45+
{
46+
uint16_t tmpfb[8] = {0};
47+
for (int i=0; i<8; i++) {
48+
for (int j=0; j<11; j++) {
49+
tmpfb[i] |= ((chunk[j] >> (7-i)) & 0x01) << j;
50+
}
51+
}
52+
for (int i=0; i<8; i++) {
53+
fb[col+i] = tmpfb[i];
54+
}
55+
}
56+
57+
void chunk2buffer(uint8_t *chunk, uint16_t size, uint16_t *buf)
58+
{
59+
for (int i=0; i<size/11; i++) {
60+
__chunk2buffer(buf, &chunk[i*11], 8 * i);
61+
}
62+
}
63+
64+
void chunk2fb(uint8_t *chunk, uint16_t size, fb_t *fb)
65+
{
66+
chunk2buffer(chunk, size, fb->buf);
67+
}
68+
69+
fb_t *chunk2newfb(uint8_t *chunk, uint16_t size)
70+
{
71+
fb_t *fb = fb_new((size*8)/11);
72+
chunk2fb(chunk, size, fb);
73+
return fb;
74+
}
75+
76+
fb_t *flash2newfb(uint32_t n)
77+
{
78+
uint8_t *buf;
79+
uint16_t size = data_flash2newmem(&buf, n);
80+
if (size == 0)
81+
return NULL;
82+
return chunk2newfb(buf, size);
83+
free(buf);
84+
}

src/data.h

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#ifndef __DATA_H__
2+
#define __DATA_H__
3+
4+
#include <stdint.h>
5+
6+
#include "fb.h"
7+
8+
typedef struct {
9+
uint8_t header[6];
10+
uint8_t flash;
11+
uint8_t marquee;
12+
uint8_t modes[8];
13+
14+
uint16_t sizes[8]; // big endian
15+
16+
uint8_t pad6[6];
17+
uint8_t timestamp[6];
18+
uint8_t pad4[4];
19+
20+
uint8_t separator[16];
21+
22+
uint8_t *bitmapdata;
23+
} data_legacy_t;
24+
25+
#define LEGACY_TRANSFER_WIDTH (16)
26+
#define LEGACY_HEADER_SIZE (sizeof(data_legacy_t) - sizeof(uint8_t *))
27+
28+
static inline uint16_t bswap16(uint16_t i) {
29+
return (i >> 8) | (i << 8);
30+
}
31+
uint32_t bigendian16_sum(uint16_t *s, int len);
32+
33+
uint32_t data_flatSave(uint8_t *data, uint32_t len);
34+
uint16_t data_flash2newmem(uint8_t **chunk, uint32_t n);
35+
36+
void chunk2buffer(uint8_t *chunk, uint16_t size, uint16_t *buf);
37+
void chunk2fb(uint8_t *chunk, uint16_t size, fb_t *fb);
38+
39+
fb_t *chunk2newfb(uint8_t *chunk, uint16_t size);
40+
fb_t *flash2newfb(uint32_t n);
41+
42+
#endif /* __DATA_H__ */

src/main.c

+10-34
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#include "leddrv.h"
55
#include "button.h"
66
#include "fb.h"
7+
#include "power.h"
8+
#include "data.h"
79

810
#include "ble/setup.h"
911
#include "ble/profile.h"
@@ -26,30 +28,6 @@ enum MODES {
2628
};
2729
#define BRIGHTNESS_LEVELS (4)
2830

29-
uint8_t test_font[][11] = {
30-
0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0xF0, 0x00, // F
31-
0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, // O
32-
0x00, 0x7C, 0xC6, 0xC6, 0x60, 0x38, 0x0C, 0xC6, 0xC6, 0x7C, 0x00, // S
33-
0x00, 0x7C, 0xC6, 0xC6, 0x60, 0x38, 0x0C, 0xC6, 0xC6, 0x7C, 0x00, // S
34-
0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, // A
35-
0x00, 0x7C, 0xC6, 0xC6, 0x60, 0x38, 0x0C, 0xC6, 0xC6, 0x7C, 0x00, // S
36-
0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, // I
37-
0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, // A
38-
};
39-
40-
void draw2fb(uint16_t *fb, int c, int col)
41-
{
42-
uint16_t tmpfb[8] = {0};
43-
for (int i=0; i<8; i++) {
44-
for (int j=0; j<11; j++) {
45-
tmpfb[i] |= ((test_font[c][j] >> (8-i)) & 0x01) << j;
46-
}
47-
}
48-
for (int i=0; i<8; i++) {
49-
fb[col+i] = tmpfb[i];
50-
}
51-
}
52-
5331
volatile int mode, brightness;
5432

5533
__HIGH_CODE
@@ -75,19 +53,17 @@ void draw_testfb()
7553
{
7654

7755
fb_t *curr_fb = fblist_currentfb();
78-
curr_fb->modes = LEFT;
7956

8057
for (int i=0; i<8; i++) {
81-
draw2fb(curr_fb->buf, i, 8 * (i + 4));
58+
fb_t *fb = flash2newfb(i);
59+
if (fb == NULL)
60+
continue;
61+
fb->modes = LEFT;
62+
fblist_append(fb);
8263
}
64+
fblist_gonext();
8365

84-
fb_t *fb_next = fb_new(8*12);
85-
fblist_append(fb_next);
86-
fb_next->modes = LEFT;
87-
88-
for (int i=4; i<12; i++) {
89-
draw2fb(fb_next->buf, i % 8, 8 * (i + 1));
90-
}
66+
fblist_drop(curr_fb);
9167
}
9268

9369
void poweroff()
@@ -170,7 +146,7 @@ int main()
170146
while (isPressed(KEY2)) {
171147
i++;
172148
if (i>10) {
173-
asm volatile("j 0x00");
149+
reset_jump();
174150
}
175151
DelayMs(200);
176152
}

src/power.h

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#ifndef __RESET_H__
2+
#define __RESET_H__
3+
4+
static inline void reset_jump()
5+
{
6+
asm volatile("j 0x00");
7+
}
8+
9+
void poweroff();
10+
11+
#endif /* __RESET_H__ */

0 commit comments

Comments
 (0)