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