aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ble/profile/legacy.c34
-rw-r--r--src/data.c84
-rw-r--r--src/data.h42
-rw-r--r--src/main.c44
-rw-r--r--src/power.h11
5 files changed, 180 insertions, 35 deletions
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 <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#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; i<size/11; i++) {
+ __chunk2buffer(buf, &chunk[i*11], 8 * i);
+ }
+}
+
+void chunk2fb(uint8_t *chunk, uint16_t size, fb_t *fb)
+{
+ chunk2buffer(chunk, size, fb->buf);
+}
+
+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 <stdint.h>
+
+#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__ */