From 86e6f0db4d8349a7efbd98ac5fe5453fb58bd82c Mon Sep 17 00:00:00 2001 From: Dien-Nhung Nguyen-Phu Date: Sun, 23 Jun 2024 19:44:32 +0700 Subject: feat: save received data from BLE to flash --- Makefile | 1 + src/ble/profile/legacy.c | 34 +++++++++++++++++++- src/data.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++ src/data.h | 42 ++++++++++++++++++++++++ src/main.c | 44 ++++++------------------- src/power.h | 11 +++++++ 6 files changed, 181 insertions(+), 35 deletions(-) create mode 100644 src/data.c create mode 100644 src/data.h create mode 100644 src/power.h diff --git a/Makefile b/Makefile index 289b0ac..ea1a881 100644 --- a/Makefile +++ b/Makefile @@ -57,6 +57,7 @@ src/ble/profile/legacy.c \ src/ble/profile/devinfo.c \ src/ble/setup.c \ src/ble/peripheral.c \ +src/data.c \ # ASM sources diff --git a/src/ble/profile/legacy.c b/src/ble/profile/legacy.c index fc775e5..2957aa5 100644 --- a/src/ble/profile/legacy.c +++ b/src/ble/profile/legacy.c @@ -1,5 +1,9 @@ #include "utils.h" +#include "../../data.h" +#include "../../power.h" +#include "../../leddrv.h" + static const uint16_t ServiceUUID = 0xFEE0; static const gattAttrType_t service = {2, (uint8_t *)&ServiceUUID}; @@ -16,7 +20,35 @@ static gattAttribute_t attr_table[] = { static bStatus_t receive(uint8_t *val, uint16_t len) { - /* TODO: implement data receiving here*/ + static uint16_t c, data_len, n; + static uint8_t *data; + if (len != LEGACY_TRANSFER_WIDTH) { + return ATT_ERR_INVALID_VALUE_SIZE; + } + if (c == 0) { + if (memcmp(val, "wang\0\0", 6)) { + return ATT_ERR_INVALID_VALUE; + } else { + data = malloc(sizeof(data_legacy_t)); + } + } + + memcpy(data + c * len, val, len); + + if (c == 1) { + data_legacy_t *d = (data_legacy_t *)data; + n = bigendian16_sum(d->sizes, 8); + data_len = LEGACY_HEADER_SIZE + LED_ROWS * n; + data = realloc(data, data_len); + } + + if (c > 2 && ((c+1) * LEGACY_TRANSFER_WIDTH) >= data_len) { + data_flatSave(data, data_len); + reset_jump(); + } + + c++; + return SUCCESS; } static bStatus_t write_handler(uint16 connHandle, gattAttribute_t *pAttr, diff --git a/src/data.c b/src/data.c new file mode 100644 index 0000000..f1a11af --- /dev/null +++ b/src/data.c @@ -0,0 +1,84 @@ +#include +#include +#include + +#include "ISP583.h" + +#include "data.h" +#include "leddrv.h" + +uint32_t bigendian16_sum(uint16_t *s, int len) +{ + uint32_t sum = 0; + while (len-- > 0) { + sum += bswap16(s[len]); + } + return sum; +} + +uint32_t data_flatSave(uint8_t *data, uint32_t len) +{ + uint32_t r = EEPROM_ERASE(0, len); + if (r) + return r; + return EEPROM_WRITE(0, data, len); +} + +uint16_t data_flash2newmem(uint8_t **chunk, uint32_t n) +{ + data_legacy_t header; + EEPROM_READ(0, &header, LEGACY_HEADER_SIZE); + + uint16_t size = bswap16(header.sizes[n]) * LED_ROWS; + if (size == 0) + return 0; + + uint16_t offs = LEGACY_HEADER_SIZE + + bigendian16_sum(header.sizes, n) * LED_ROWS; + + *chunk = malloc(size); + EEPROM_READ(offs, *chunk, size); + return size; +} + +static void __chunk2buffer(uint16_t *fb, uint8_t *chunk, int col) +{ + uint16_t tmpfb[8] = {0}; + for (int i=0; i<8; i++) { + for (int j=0; j<11; j++) { + tmpfb[i] |= ((chunk[j] >> (7-i)) & 0x01) << j; + } + } + for (int i=0; i<8; i++) { + fb[col+i] = tmpfb[i]; + } +} + +void chunk2buffer(uint8_t *chunk, uint16_t size, uint16_t *buf) +{ + for (int i=0; ibuf); +} + +fb_t *chunk2newfb(uint8_t *chunk, uint16_t size) +{ + fb_t *fb = fb_new((size*8)/11); + chunk2fb(chunk, size, fb); + return fb; +} + +fb_t *flash2newfb(uint32_t n) +{ + uint8_t *buf; + uint16_t size = data_flash2newmem(&buf, n); + if (size == 0) + return NULL; + return chunk2newfb(buf, size); + free(buf); +} diff --git a/src/data.h b/src/data.h new file mode 100644 index 0000000..813176d --- /dev/null +++ b/src/data.h @@ -0,0 +1,42 @@ +#ifndef __DATA_H__ +#define __DATA_H__ + +#include + +#include "fb.h" + +typedef struct { + uint8_t header[6]; + uint8_t flash; + uint8_t marquee; + uint8_t modes[8]; + + uint16_t sizes[8]; // big endian + + uint8_t pad6[6]; + uint8_t timestamp[6]; + uint8_t pad4[4]; + + uint8_t separator[16]; + + uint8_t *bitmapdata; +} data_legacy_t; + +#define LEGACY_TRANSFER_WIDTH (16) +#define LEGACY_HEADER_SIZE (sizeof(data_legacy_t) - sizeof(uint8_t *)) + +static inline uint16_t bswap16(uint16_t i) { + return (i >> 8) | (i << 8); +} +uint32_t bigendian16_sum(uint16_t *s, int len); + +uint32_t data_flatSave(uint8_t *data, uint32_t len); +uint16_t data_flash2newmem(uint8_t **chunk, uint32_t n); + +void chunk2buffer(uint8_t *chunk, uint16_t size, uint16_t *buf); +void chunk2fb(uint8_t *chunk, uint16_t size, fb_t *fb); + +fb_t *chunk2newfb(uint8_t *chunk, uint16_t size); +fb_t *flash2newfb(uint32_t n); + +#endif /* __DATA_H__ */ diff --git a/src/main.c b/src/main.c index 613504e..5c0aa26 100644 --- a/src/main.c +++ b/src/main.c @@ -4,6 +4,8 @@ #include "leddrv.h" #include "button.h" #include "fb.h" +#include "power.h" +#include "data.h" #include "ble/setup.h" #include "ble/profile.h" @@ -26,30 +28,6 @@ enum MODES { }; #define BRIGHTNESS_LEVELS (4) -uint8_t test_font[][11] = { - 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0xF0, 0x00, // F - 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, // O - 0x00, 0x7C, 0xC6, 0xC6, 0x60, 0x38, 0x0C, 0xC6, 0xC6, 0x7C, 0x00, // S - 0x00, 0x7C, 0xC6, 0xC6, 0x60, 0x38, 0x0C, 0xC6, 0xC6, 0x7C, 0x00, // S - 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, // A - 0x00, 0x7C, 0xC6, 0xC6, 0x60, 0x38, 0x0C, 0xC6, 0xC6, 0x7C, 0x00, // S - 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, // I - 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, // A -}; - -void draw2fb(uint16_t *fb, int c, int col) -{ - uint16_t tmpfb[8] = {0}; - for (int i=0; i<8; i++) { - for (int j=0; j<11; j++) { - tmpfb[i] |= ((test_font[c][j] >> (8-i)) & 0x01) << j; - } - } - for (int i=0; i<8; i++) { - fb[col+i] = tmpfb[i]; - } -} - volatile int mode, brightness; __HIGH_CODE @@ -75,19 +53,17 @@ void draw_testfb() { fb_t *curr_fb = fblist_currentfb(); - curr_fb->modes = LEFT; for (int i=0; i<8; i++) { - draw2fb(curr_fb->buf, i, 8 * (i + 4)); + fb_t *fb = flash2newfb(i); + if (fb == NULL) + continue; + fb->modes = LEFT; + fblist_append(fb); } + fblist_gonext(); - fb_t *fb_next = fb_new(8*12); - fblist_append(fb_next); - fb_next->modes = LEFT; - - for (int i=4; i<12; i++) { - draw2fb(fb_next->buf, i % 8, 8 * (i + 1)); - } + fblist_drop(curr_fb); } void poweroff() @@ -170,7 +146,7 @@ int main() while (isPressed(KEY2)) { i++; if (i>10) { - asm volatile("j 0x00"); + reset_jump(); } DelayMs(200); } diff --git a/src/power.h b/src/power.h new file mode 100644 index 0000000..4d418a0 --- /dev/null +++ b/src/power.h @@ -0,0 +1,11 @@ +#ifndef __RESET_H__ +#define __RESET_H__ + +static inline void reset_jump() +{ + asm volatile("j 0x00"); +} + +void poweroff(); + +#endif /* __RESET_H__ */ -- cgit v1.2.3