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 char buffer[N * 2 ];
41+
42+ static char write_buf[FPUTC_BUF_SIZE];
43+ static size_t write_buf_num_bytes = 0 ;
44+ static size_t bytes_written_fputc = 0 ;
45+ static size_t bytes_written_flash = 0 ;
46+ static uint32_t flash_addr = 0 ;
47+
48+ /* *************************************************************************************
49+ PUBLIC FUNCTIONS
50+ **************************************************************************************/
51+
52+ void lzss_init (uint32_t const sketch_start)
53+ {
54+ SKETCH_START = sketch_start;
55+ flash_addr = sketch_start;
56+ LZSS_FILE_SIZE = fileUtils.listFile (UPDATE_FILE_NAME_LZSS);
57+ }
58+
59+ void lzss_flush ()
60+ {
61+ bytes_written_fputc += write_buf_num_bytes;
62+
63+ /* Only write to the flash once we've surpassed
64+ * the SBU in the update binary.
65+ */
66+ if (bytes_written_fputc > (SKETCH_START - 0x2000 ))
67+ {
68+ mcu_flash.write ((void *)flash_addr, write_buf, write_buf_num_bytes);
69+ flash_addr += write_buf_num_bytes;
70+ }
71+
72+ write_buf_num_bytes = 0 ;
73+ }
74+
75+ /* *************************************************************************************
76+ PRIVATE FUNCTIONS
77+ **************************************************************************************/
78+
79+ void lzss_fputc (int const c)
80+ {
81+ /* Buffer the decompressed data into a buffer so
82+ * we can perform block writes and don't need to
83+ * write every byte singly on the flash (which
84+ * wouldn't be possible anyway).
85+ */
86+ write_buf[write_buf_num_bytes] = static_cast <char >(c);
87+ write_buf_num_bytes++;
88+
89+ /* The write buffer is full of decompressed
90+ * data, write it to the flash now.
91+ */
92+ if (write_buf_num_bytes == FPUTC_BUF_SIZE)
93+ lzss_flush ();
94+ }
95+
96+ int lzss_fgetc ()
97+ {
98+ static uint8_t read_buf[FGETC_BUF_SIZE];
99+ static size_t read_buf_pos = FGETC_BUF_SIZE;
100+ static size_t bytes_read_fgetc = 0 ;
101+ static size_t bytes_read_from_modem = 0 ;
102+
103+ /* lzss_file_size is set within SBUBoot:main
104+ * and contains the size of the LZSS file. Once
105+ * all those bytes have been read its time to return
106+ * LZSS_EOF in order to signal that the end of
107+ * the file has been reached.
108+ */
109+ if (bytes_read_fgetc == LZSS_FILE_SIZE)
110+ return LZSS_EOF;
111+
112+ /* If there is no data left to be read from the read buffer
113+ * than read a new block and store it into the read buffer.
114+ */
115+ if (read_buf_pos == FGETC_BUF_SIZE)
116+ {
117+ /* Read the next block from the flash memory. */
118+ bytes_read_from_modem += fileUtils.readBlock (UPDATE_FILE_NAME_LZSS, bytes_read_from_modem, FGETC_BUF_SIZE, read_buf);
119+ /* Reset the read buffer position. */
120+ read_buf_pos = 0 ;
121+ }
122+
123+ uint8_t const c = read_buf[read_buf_pos];
124+ read_buf_pos++;
125+ bytes_read_fgetc++;
126+
127+ return c;
128+ }
129+
130+ /* *************************************************************************************
131+ LZSS FUNCTIONS
132+ **************************************************************************************/
133+
134+ void putbit1 (void )
135+ {
136+ bit_buffer |= bit_mask;
137+ if ((bit_mask >>= 1 ) == 0 ) {
138+ lzss_fputc (bit_buffer);
139+ bit_buffer = 0 ; bit_mask = 128 ;
140+ }
141+ }
142+
143+ void putbit0 (void )
144+ {
145+ if ((bit_mask >>= 1 ) == 0 ) {
146+ lzss_fputc (bit_buffer);
147+ bit_buffer = 0 ; bit_mask = 128 ;
148+ }
149+ }
150+
151+ void output1 (int c)
152+ {
153+ int mask;
154+
155+ putbit1 ();
156+ mask = 256 ;
157+ while (mask >>= 1 ) {
158+ if (c & mask) putbit1 ();
159+ else putbit0 ();
160+ }
161+ }
162+
163+ void output2 (int x, int y)
164+ {
165+ int mask;
166+
167+ putbit0 ();
168+ mask = N;
169+ while (mask >>= 1 ) {
170+ if (x & mask) putbit1 ();
171+ else putbit0 ();
172+ }
173+ mask = (1 << EJ);
174+ while (mask >>= 1 ) {
175+ if (y & mask) putbit1 ();
176+ else putbit0 ();
177+ }
178+ }
179+
180+ int getbit (int n) /* get n bits */
181+ {
182+ int i, x;
183+ static int buf, mask = 0 ;
184+
185+ x = 0 ;
186+ for (i = 0 ; i < n; i++) {
187+ if (mask == 0 ) {
188+ if ((buf = lzss_fgetc ()) == LZSS_EOF) return LZSS_EOF;
189+ mask = 128 ;
190+ }
191+ x <<= 1 ;
192+ if (buf & mask) x++;
193+ mask >>= 1 ;
194+ }
195+ return x;
196+ }
197+
198+ void lzss_decode (void )
199+ {
200+ int i, j, k, r, c;
201+
202+ for (i = 0 ; i < N - F; i++) buffer[i] = ' ' ;
203+ r = N - F;
204+ while ((c = getbit (1 )) != LZSS_EOF) {
205+ if (c) {
206+ if ((c = getbit (8 )) == LZSS_EOF) break ;
207+ lzss_fputc (c);
208+ buffer[r++] = c; r &= (N - 1 );
209+ } else {
210+ if ((i = getbit (EI)) == LZSS_EOF) break ;
211+ if ((j = getbit (EJ)) == LZSS_EOF) break ;
212+ for (k = 0 ; k <= j + 1 ; k++) {
213+ c = buffer[(i + k) & (N - 1 )];
214+ lzss_fputc (c);
215+ buffer[r++] = c; r &= (N - 1 );
216+ }
217+ }
218+ }
219+ }
0 commit comments