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