1+ /* *************************************************************************************
2+ INCLUDE
3+ **************************************************************************************/
4+
5+ #include " lzss.h"
6+
7+ #include < stdlib.h>
8+ #include < stdint.h>
9+
10+ #include < MKRNB.h>
11+ #include < FlashStorage.h>
12+
13+ /* *************************************************************************************
14+ DEFINE
15+ **************************************************************************************/
16+
17+ #define EI 11 /* typically 10..13 */
18+ #define EJ 4 /* typically 4..5 */
19+ #define P 1 /* If match length <= P then output one character */
20+ #define N (1 << EI) /* buffer size */
21+ #define F ((1 << EJ) + 1 ) /* lookahead buffer size */
22+
23+ #define LZSS_EOF (-1 )
24+
25+ #define FPUTC_BUF_SIZE (512 )
26+ #define FGETC_BUF_SIZE (512 )
27+
28+ /* *************************************************************************************
29+ GLOBAL VARIABLES
30+ **************************************************************************************/
31+
32+ extern NBFileUtils fileUtils;
33+ extern FlashClass mcu_flash;
34+ extern const char * UPDATE_FILE_NAME_LZSS;
35+
36+ static uint32_t SKETCH_START = 0 ;
37+ static uint32_t LZSS_FILE_SIZE = 0 ;
38+
39+ int bit_buffer = 0 , bit_mask = 128 ;
40+ unsigned long codecount = 0 , textcount = 0 ;
41+ unsigned char buffer[N * 2 ];
42+
43+ static char write_buf[FPUTC_BUF_SIZE];
44+ static size_t write_buf_num_bytes = 0 ;
45+ static size_t bytes_written_fputc = 0 ;
46+ static size_t bytes_written_flash = 0 ;
47+ static uint32_t flash_addr = 0 ;
48+
49+ bool fromLZSStoBIN = true ;
50+ bool append = false ;
51+ bool endOfFile = false ;
52+
53+ /* *************************************************************************************
54+ PUBLIC FUNCTIONS
55+ **************************************************************************************/
56+
57+ void lzss_init (uint32_t const sketch_start, bool LZSStoBIN)
58+ {
59+ fromLZSStoBIN = LZSStoBIN;
60+ if (LZSStoBIN) {
61+ SKETCH_START = sketch_start;
62+ flash_addr = sketch_start;
63+ LZSS_FILE_SIZE = fileUtils.listFile (" UPDATE.BIN.LZSS" );
64+ }
65+ }
66+
67+ void lzss_flush ()
68+ {
69+ bytes_written_fputc += write_buf_num_bytes;
70+
71+ if (fromLZSStoBIN) {
72+ /* Only write to the flash once we've surpassed
73+ * the SBU in the update binary.
74+ */
75+ if (bytes_written_fputc > (SKETCH_START - 0x2000 ))
76+ {
77+ mcu_flash.write ((void *)flash_addr, write_buf, write_buf_num_bytes);
78+ flash_addr += write_buf_num_bytes;
79+ }
80+ } else {
81+ fileUtils.downloadFile (" UPDATE.BIN.LZSS" , write_buf, write_buf_num_bytes, append);
82+ append = true ;
83+ }
84+
85+ write_buf_num_bytes = 0 ;
86+ }
87+
88+ /* *************************************************************************************
89+ PRIVATE FUNCTIONS
90+ **************************************************************************************/
91+
92+ void lzss_fputc (int const c)
93+ {
94+ /* Buffer the decompressed data into a buffer so
95+ * we can perform block writes and don't need to
96+ * write every byte singly on the flash (which
97+ * wouldn't be possible anyway).
98+ */
99+ write_buf[write_buf_num_bytes] = static_cast <char >(c);
100+ write_buf_num_bytes++;
101+
102+ /* The write buffer is full of decompressed
103+ * data, write it to the flash now.
104+ */
105+ if (write_buf_num_bytes == FPUTC_BUF_SIZE || endOfFile)
106+ lzss_flush ();
107+ }
108+
109+ /* *************************************************************************************
110+ LZSS FUNCTIONS
111+ **************************************************************************************/
112+
113+ void putbit1 (void )
114+ {
115+ bit_buffer |= bit_mask;
116+ if ((bit_mask >>= 1 ) == 0 ) {
117+ lzss_fputc (bit_buffer);
118+ bit_buffer = 0 ; bit_mask = 128 ;
119+ }
120+ }
121+
122+ void putbit0 (void )
123+ {
124+ if ((bit_mask >>= 1 ) == 0 ) {
125+ lzss_fputc (bit_buffer);
126+ bit_buffer = 0 ; bit_mask = 128 ;
127+ }
128+ }
129+
130+ void flush_bit_buffer (void )
131+ {
132+ if (bit_mask != 128 ) {
133+ // if (fputc(bit_buffer, outfile) == EOF) error();
134+ lzss_fputc (bit_buffer);
135+ codecount++;
136+ }
137+ }
138+
139+ void output1 (int c)
140+ {
141+ int mask;
142+
143+ putbit1 ();
144+ mask = 256 ;
145+ while (mask >>= 1 ) {
146+ if (c & mask) putbit1 ();
147+ else putbit0 ();
148+ }
149+ }
150+
151+ void output2 (int x, int y)
152+ {
153+ int mask;
154+
155+ putbit0 ();
156+ mask = N;
157+ while (mask >>= 1 ) {
158+ if (x & mask) putbit1 ();
159+ else putbit0 ();
160+ }
161+ mask = (1 << EJ);
162+ while (mask >>= 1 ) {
163+ if (y & mask) putbit1 ();
164+ else putbit0 ();
165+ }
166+ }
167+
168+ int lzss_encode (const char buf_in[], uint32_t size)
169+ {
170+ int i, j, f1, x, y, r, s, bufferend, c;
171+
172+ for (i = 0 ; i < N - F; i++) buffer[i] = ' ' ;
173+ for (i = N - F; i < N * 2 ; i++) {
174+ if (textcount >= size) {
175+ endOfFile = true ;
176+ break ;
177+ } else {
178+ buffer[i] = buf_in[textcount];
179+ textcount++;
180+ }
181+ }
182+ bufferend = i; r = N - F; s = 0 ;
183+ while (r < bufferend) {
184+ f1 = (F <= bufferend - r) ? F : bufferend - r;
185+ x = 0 ; y = 1 ; c = buffer[r];
186+ for (i = r - 1 ; i >= s; i--)
187+ if (buffer[i] == c) {
188+ for (j = 1 ; j < f1; j++)
189+ if (buffer[i + j] != buffer[r + j]) break ;
190+ if (j > y) {
191+ x = i; y = j;
192+ }
193+ }
194+ if (y <= P) { y = 1 ; output1 (c); }
195+ else output2 (x & (N - 1 ), y - 2 );
196+ r += y; s += y;
197+ if (r >= N * 2 - F) {
198+ for (i = 0 ; i < N; i++) buffer[i] = buffer[i + N];
199+ bufferend -= N; r -= N; s -= N;
200+ while (bufferend < N * 2 ) {
201+ if (textcount >= size) {
202+ endOfFile = true ;
203+ break ;
204+ } else {
205+ buffer[bufferend++] = buf_in[textcount];
206+ textcount++;
207+ }
208+ }
209+ }
210+ }
211+ flush_bit_buffer ();
212+
213+ return bytes_written_fputc;
214+ }
0 commit comments