Skip to content

Commit 71b410b

Browse files
authored
Merge pull request #551 from giulcioffi/sbu-lzss
Add LZSS encoding/decoding for MKRNB 1500 SBU
2 parents 4544e2e + 768d754 commit 71b410b

File tree

7 files changed

+2938
-2330
lines changed

7 files changed

+2938
-2330
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#include <MKRNB.h>
2+
#include <SBU.h>
3+
4+
#include "lzssEncode.h"
5+
6+
static char const BINARY[] =
7+
{
8+
#include "Binary.h"
9+
};
10+
11+
static char const CHECK_FILE[] =
12+
{
13+
"OK"
14+
};
15+
16+
static constexpr char CHECK_FILE_NAME[] = "UPDATE.OK";
17+
const char * UPDATE_FILE_NAME_LZSS = "UPDATE.BIN.LZSS";
18+
19+
NBFileUtils fileUtils;
20+
bool update_available = false;
21+
22+
void setup() {
23+
Serial.begin(9600);
24+
while (!Serial) { }
25+
26+
unsigned long const start = millis();
27+
for (unsigned long now = millis(); !Serial && ((now - start) < 5000); now = millis()) { };
28+
29+
Serial.print("Accessing SARA Filesystem... ");
30+
if (!fileUtils.begin(false)) {
31+
Serial.println("failed.");
32+
return;
33+
34+
}
35+
Serial.println("OK");
36+
37+
uint32_t bytes_to_write = sizeof(BINARY);
38+
Serial.print("Size of BINARY.H: ");
39+
Serial.println(bytes_to_write);
40+
41+
Serial.print("Encoding \"BINARY.H\" into \"UPDATE.BIN.LZSS\" and writing it into the Sara-R410M module ... ");
42+
43+
//Encode into .lzss and write to the Sara modem
44+
int bytes_written = lzss_encode(BINARY, bytes_to_write);
45+
46+
if (bytes_written == 0) {
47+
Serial.println("something went wrong!");
48+
} else {
49+
Serial.println("OK!");
50+
}
51+
52+
Serial.print("Size of UPDATE.BIN.LZSS: ");
53+
Serial.println(bytes_written);
54+
55+
auto status = 0;
56+
while (status != 2) {
57+
status = fileUtils.createFile(CHECK_FILE_NAME, CHECK_FILE, 2);
58+
delay(100);
59+
}
60+
61+
Serial.println("Please type \"restart\" to apply the update");
62+
update_available = true;
63+
}
64+
65+
66+
void loop() {
67+
if (update_available == true) {
68+
String command = Serial.readStringUntil('\n');
69+
if (command.indexOf("restart") >= 0) {
70+
NVIC_SystemReset();
71+
}
72+
}
73+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
/**************************************************************************************
2+
INCLUDE
3+
**************************************************************************************/
4+
5+
#include "lzssEncode.h"
6+
7+
#include <stdlib.h>
8+
#include <stdint.h>
9+
10+
#include <MKRNB.h>
11+
12+
/**************************************************************************************
13+
DEFINE
14+
**************************************************************************************/
15+
16+
#define EI 11 /* typically 10..13 */
17+
#define EJ 4 /* typically 4..5 */
18+
#define P 1 /* If match length <= P then output one character */
19+
#define N (1 << EI) /* buffer size */
20+
#define F ((1 << EJ) + 1) /* lookahead buffer size */
21+
22+
#define LZSS_EOF (-1)
23+
24+
#define FPUTC_BUF_SIZE (512)
25+
#define FGETC_BUF_SIZE (512)
26+
27+
/**************************************************************************************
28+
GLOBAL VARIABLES
29+
**************************************************************************************/
30+
31+
extern NBFileUtils fileUtils;
32+
extern const char * UPDATE_FILE_NAME_LZSS;
33+
34+
int bit_buffer = 0, bit_mask = 128;
35+
unsigned long textcount = 0;
36+
unsigned char buffer[N * 2];
37+
38+
static char write_buf[FPUTC_BUF_SIZE];
39+
static size_t write_buf_num_bytes = 0;
40+
static size_t bytes_written_fputc = 0;
41+
42+
bool append = false;
43+
bool endOfFile = false;
44+
45+
/**************************************************************************************
46+
PUBLIC FUNCTIONS
47+
**************************************************************************************/
48+
49+
void lzss_flush()
50+
{
51+
bytes_written_fputc += write_buf_num_bytes;
52+
53+
fileUtils.downloadFile(UPDATE_FILE_NAME_LZSS, write_buf, write_buf_num_bytes, append); //UPDATE.BIN.LZSS
54+
append = true;
55+
56+
write_buf_num_bytes = 0;
57+
}
58+
59+
/**************************************************************************************
60+
PRIVATE FUNCTIONS
61+
**************************************************************************************/
62+
63+
void lzss_fputc(int const c)
64+
{
65+
/* Buffer the compressed data into a buffer so
66+
* we can perform block writes and don't need to
67+
* write every byte singly on the modem
68+
*/
69+
write_buf[write_buf_num_bytes] = static_cast<char>(c);
70+
write_buf_num_bytes++;
71+
72+
/* The write buffer is full of compressed
73+
* data, write it to the modem now.
74+
*/
75+
if (write_buf_num_bytes == FPUTC_BUF_SIZE || endOfFile)
76+
lzss_flush();
77+
}
78+
79+
/**************************************************************************************
80+
LZSS FUNCTIONS
81+
**************************************************************************************/
82+
83+
void putbit1(void)
84+
{
85+
bit_buffer |= bit_mask;
86+
if ((bit_mask >>= 1) == 0) {
87+
lzss_fputc(bit_buffer);
88+
bit_buffer = 0; bit_mask = 128;
89+
}
90+
}
91+
92+
void putbit0(void)
93+
{
94+
if ((bit_mask >>= 1) == 0) {
95+
lzss_fputc(bit_buffer);
96+
bit_buffer = 0; bit_mask = 128;
97+
}
98+
}
99+
100+
void flush_bit_buffer(void)
101+
{
102+
if (bit_mask != 128) {
103+
lzss_fputc(bit_buffer);
104+
}
105+
}
106+
107+
void output1(int c)
108+
{
109+
int mask;
110+
111+
putbit1();
112+
mask = 256;
113+
while (mask >>= 1) {
114+
if (c & mask) putbit1();
115+
else putbit0();
116+
}
117+
}
118+
119+
void output2(int x, int y)
120+
{
121+
int mask;
122+
123+
putbit0();
124+
mask = N;
125+
while (mask >>= 1) {
126+
if (x & mask) putbit1();
127+
else putbit0();
128+
}
129+
mask = (1 << EJ);
130+
while (mask >>= 1) {
131+
if (y & mask) putbit1();
132+
else putbit0();
133+
}
134+
}
135+
136+
int lzss_encode(const char buf_in[], uint32_t size)
137+
{
138+
int i, j, f1, x, y, r, s, bufferend, c;
139+
140+
for (i = 0; i < N - F; i++) buffer[i] = ' ';
141+
for (i = N - F; i < N * 2; i++) {
142+
if (textcount >= size) {
143+
endOfFile = true;
144+
break;
145+
} else {
146+
buffer[i] = buf_in[textcount];
147+
textcount++;
148+
}
149+
}
150+
bufferend = i; r = N - F; s = 0;
151+
while (r < bufferend) {
152+
f1 = (F <= bufferend - r) ? F : bufferend - r;
153+
x = 0; y = 1; c = buffer[r];
154+
for (i = r - 1; i >= s; i--)
155+
if (buffer[i] == c) {
156+
for (j = 1; j < f1; j++)
157+
if (buffer[i + j] != buffer[r + j]) break;
158+
if (j > y) {
159+
x = i; y = j;
160+
}
161+
}
162+
if (y <= P) { y = 1; output1(c); }
163+
else output2(x & (N - 1), y - 2);
164+
r += y; s += y;
165+
if (r >= N * 2 - F) {
166+
for (i = 0; i < N; i++) buffer[i] = buffer[i + N];
167+
bufferend -= N; r -= N; s -= N;
168+
while (bufferend < N * 2) {
169+
if (textcount >= size) {
170+
endOfFile = true;
171+
break;
172+
} else {
173+
buffer[bufferend++] = buf_in[textcount];
174+
textcount++;
175+
}
176+
}
177+
}
178+
}
179+
flush_bit_buffer();
180+
181+
return bytes_written_fputc;
182+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#ifndef SBU_LZSS_H_
2+
#define SBU_LZSS_H_
3+
4+
/**************************************************************************************
5+
INCLUDE
6+
**************************************************************************************/
7+
8+
#include <stdint.h>
9+
10+
/**************************************************************************************
11+
FUNCTION DEFINITION
12+
**************************************************************************************/
13+
14+
void lzss_flush();
15+
int lzss_encode(const char buf_in[], uint32_t size);
16+
17+
#endif /* SBU_LZSS_H_ */

0 commit comments

Comments
 (0)