diff --git a/Adafruit_MTK3329_GPS/GPStest/GPStest.ino b/Adafruit_MTK3329_GPS/GPStest/GPStest.ino index 805387d9b..995c18139 100644 --- a/Adafruit_MTK3329_GPS/GPStest/GPStest.ino +++ b/Adafruit_MTK3329_GPS/GPStest/GPStest.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2019 Anne Barela for Adafruit Industries +// +// SPDX-License-Identifier: MIT + // Test code for Adafruit GPS modules using MTK driver // such as www.adafruit.com/products/660 (discontinued) // For new use see www.adafruit.com/products/746 (needs different code) diff --git a/Adafruit_X2_Time_Ball/Arduino/LEDstream/LEDstream.ino b/Adafruit_X2_Time_Ball/Arduino/LEDstream/LEDstream.ino index 986450d39..b82c559bf 100644 --- a/Adafruit_X2_Time_Ball/Arduino/LEDstream/LEDstream.ino +++ b/Adafruit_X2_Time_Ball/Arduino/LEDstream/LEDstream.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2019 Anne Barela for Adafruit Industries +// +// SPDX-License-Identifier: MIT + // Arduino "bridge" code between host computer and WS2801-based digital // RGB LED pixels (e.g. Adafruit product ID #322). Intended for use // with USB-native boards such as Teensy or Adafruit 32u4 Breakout; diff --git a/Adafruit_X2_Time_Ball/Arduino/LEDtest/LEDtest.ino b/Adafruit_X2_Time_Ball/Arduino/LEDtest/LEDtest.ino index a5fc57068..7d2a5f7e6 100644 --- a/Adafruit_X2_Time_Ball/Arduino/LEDtest/LEDtest.ino +++ b/Adafruit_X2_Time_Ball/Arduino/LEDtest/LEDtest.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2019 Anne Barela for Adafruit Industries +// +// SPDX-License-Identifier: MIT + /***************************************************************************** Sketch for testing WS2801 LED strands - lights one LED along length of strand. Because only one LED is lit at a time, can safely be powered from Arduino +5V. diff --git a/CircuitPython_AT_Hand_Raiser/code.py b/CircuitPython_AT_Hand_Raiser/code.py index 6ef5dcbc9..5d322d752 100644 --- a/CircuitPython_AT_Hand_Raiser/code.py +++ b/CircuitPython_AT_Hand_Raiser/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 Anne Barela for Adafruit Industries +# +# SPDX-License-Identifier: MIT + # ATMakers HandUp # Listens to the USB Serial port and responds to incoming strings # Sets appropriate colors on the DotStar LED diff --git a/CircuitPython_PyPaint/code.py b/CircuitPython_PyPaint/code.py index fa280b95a..d4a6354a5 100644 --- a/CircuitPython_PyPaint/code.py +++ b/CircuitPython_PyPaint/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 Dave Astels for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """ Paint for PyPortal, PyBadge, PyGamer, and the like. diff --git a/Data_Logging_with_Feather_and_CircuitPython/code.py b/Data_Logging_with_Feather_and_CircuitPython/code.py index cf79c37b3..360405559 100644 --- a/Data_Logging_with_Feather_and_CircuitPython/code.py +++ b/Data_Logging_with_Feather_and_CircuitPython/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2018 Kattni Rembor for Adafruit Industries +# +# SPDX-License-Identifier: MIT + import time import analogio diff --git a/FunHouse_Fume_Extractor/code.py b/FunHouse_Fume_Extractor/code.py index 7b0f38e94..c99ea4278 100644 --- a/FunHouse_Fume_Extractor/code.py +++ b/FunHouse_Fume_Extractor/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2021 Liz Clark for Adafruit Industries +# +# SPDX-License-Identifier: MIT + import time import board import simpleio diff --git a/Gemma_Firewalker_Lite_Sneakers/Gemma_Firewalker_Lite_Sneakers.ino b/Gemma_Firewalker_Lite_Sneakers/Gemma_Firewalker_Lite_Sneakers.ino index af0607401..125e61c1a 100644 --- a/Gemma_Firewalker_Lite_Sneakers/Gemma_Firewalker_Lite_Sneakers.ino +++ b/Gemma_Firewalker_Lite_Sneakers/Gemma_Firewalker_Lite_Sneakers.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2018 Mikey Sklar for Adafruit Industries +// +// SPDX-License-Identifier: MIT + /*------------------------------------------------------------------------ Gemma "Firewalker Lite" sneakers sketch. Uses the following Adafruit parts (X2 for two shoes): diff --git a/Gemma_Firewalker_Lite_Sneakers/code.py b/Gemma_Firewalker_Lite_Sneakers/code.py index 3af06fdf9..6739e9911 100644 --- a/Gemma_Firewalker_Lite_Sneakers/code.py +++ b/Gemma_Firewalker_Lite_Sneakers/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2018 Phillip Burgess for Adafruit Industries +# +# SPDX-License-Identifier: MIT + # Gemma "Firewalker Lite" sneakers # - Uses the following Adafruit parts (X2 for two shoes): # * Gemma M0 3V microcontroller (#3501) diff --git a/IoT_Party_Parrot/code.py b/IoT_Party_Parrot/code.py index e01bc1257..78dfacb74 100644 --- a/IoT_Party_Parrot/code.py +++ b/IoT_Party_Parrot/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Liz Clark for Adafruit Industries +# +# SPDX-License-Identifier: MIT + import time import board import displayio diff --git a/IoT_Party_Parrot/secrets.py b/IoT_Party_Parrot/secrets.py index eb8b6e953..39bdad947 100644 --- a/IoT_Party_Parrot/secrets.py +++ b/IoT_Party_Parrot/secrets.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Liz Clark for Adafruit Industries +# +# SPDX-License-Identifier: MIT + # This file is where you keep secret settings, passwords, and tokens! # If you put them in the code you risk committing that info or sharing it diff --git a/MIDI_Solenoid_Drummer/MIDI_Solenoid_Drummer.ino b/MIDI_Solenoid_Drummer/MIDI_Solenoid_Drummer.ino index b00f511c1..e5bafa99e 100644 --- a/MIDI_Solenoid_Drummer/MIDI_Solenoid_Drummer.ino +++ b/MIDI_Solenoid_Drummer/MIDI_Solenoid_Drummer.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2018 Collin Cunningham for Adafruit Industries +// +// SPDX-License-Identifier: MIT + /* MIDI Solenoid Drummer * for use with Adafruit Feather + Crickit Featherwing * assumes a 5V solenoid connected to each of Crickit's four Drive ports diff --git a/NeoKey_Trinkey_Centipede/code.py b/NeoKey_Trinkey_Centipede/code.py index e1d1ecc8b..39d1c03e9 100644 --- a/NeoKey_Trinkey_Centipede/code.py +++ b/NeoKey_Trinkey_Centipede/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2021 Eva Herrada for Adafruit Industries +# +# SPDX-License-Identifier: MIT + import time import math import board diff --git a/NeoPixel_Tiara/code.py b/NeoPixel_Tiara/code.py index f0fa5f014..32b4fc050 100644 --- a/NeoPixel_Tiara/code.py +++ b/NeoPixel_Tiara/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2017 Mikey Sklar for Adafruit Industries +# +# SPDX-License-Identifier: MIT + import time import board diff --git a/Ocean_Resin_Lightbox/code.py b/Ocean_Resin_Lightbox/code.py index 2e494bfbd..f8469bfe4 100644 --- a/Ocean_Resin_Lightbox/code.py +++ b/Ocean_Resin_Lightbox/code.py @@ -1,3 +1,8 @@ +# SPDX-FileCopyrightText: 2020 Jeff Epler for Adafruit Industries +# SPDX-FileCopyrightText: 2020 Limor Fried for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """ RGB Matrix Ocean Scroller Adafruit invests time and resources providing this open source code. diff --git a/PMS5003_Air_Quality_Sensor/PMS5003_Arduino/PMS5003_Arduino.ino b/PMS5003_Air_Quality_Sensor/PMS5003_Arduino/PMS5003_Arduino.ino index da8ac8f3d..d1602573c 100644 --- a/PMS5003_Air_Quality_Sensor/PMS5003_Arduino/PMS5003_Arduino.ino +++ b/PMS5003_Air_Quality_Sensor/PMS5003_Arduino/PMS5003_Arduino.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2017 Limor Fried for Adafruit Industries +// +// SPDX-License-Identifier: MIT + // On Leonardo/Micro or others with hardware serial, use those! // uncomment this line: // #define pmsSerial Serial1 diff --git a/PyPortal_Hurricane_Tracker/code.py b/PyPortal_Hurricane_Tracker/code.py index 26ac1a1d8..139473575 100755 --- a/PyPortal_Hurricane_Tracker/code.py +++ b/PyPortal_Hurricane_Tracker/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Carter Nelson for Adafruit Industries +# +# SPDX-License-Identifier: MIT + import time import math import board diff --git a/PyPortal_ObliqueStrategies/code.py b/PyPortal_ObliqueStrategies/code.py index ce68fb066..b19b50a62 100755 --- a/PyPortal_ObliqueStrategies/code.py +++ b/PyPortal_ObliqueStrategies/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 Collin Cunningham for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """ This code will display a random strategy from strategies.py when the PyPortal screen is pressed. See the original Oblique Strategies diff --git a/PyPortal_ObliqueStrategies/strategies.py b/PyPortal_ObliqueStrategies/strategies.py index 374cf2440..77e8896bd 100755 --- a/PyPortal_ObliqueStrategies/strategies.py +++ b/PyPortal_ObliqueStrategies/strategies.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 Collin Cunningham for Adafruit Industries +# +# SPDX-License-Identifier: MIT + strategies = [ "Abandon normal instruments", "Accept advice", diff --git a/SHARP_BadApple/SHARP_BadApple.ino b/SHARP_BadApple/SHARP_BadApple.ino index d9d847181..b7fab741e 100755 --- a/SHARP_BadApple/SHARP_BadApple.ino +++ b/SHARP_BadApple/SHARP_BadApple.ino @@ -1,222 +1,226 @@ -// Bad Apple for ESP32 with OLED SSD1306 | 2018 by Hackerspace-FFM.de | MIT-License. -// Adapted for Sharp Memory display + Itsy Bitsy M4 - put video.hs on QSPI storage using CircuitPython -#include "heatshrink_decoder.h" - -#include "SdFat.h" -#include "Adafruit_SPIFlash.h" -#include -#define BLACK 0 -#define WHITE 1 - -#define SCALE 3 - - -#if HEATSHRINK_DYNAMIC_ALLOC -#error HEATSHRINK_DYNAMIC_ALLOC must be false for static allocation test suite. -#endif - -static heatshrink_decoder hsd; - -// global storage for putPixels -int16_t curr_x = 0; -int16_t curr_y = 0; - -// global storage for decodeRLE -int32_t runlength = -1; -int32_t c_to_dup = -1; - -uint32_t lastRefresh = 0; - -#define SHARP_SS A5 -Adafruit_SharpMem display(&SPI, SHARP_SS, 400, 240, 3000000); -#define X_OFFSET (400 - SCALE*128) / 2 -#define Y_OFFSET (240 - SCALE*64) / 2 - -Adafruit_FlashTransport_QSPI flashTransport; -Adafruit_SPIFlash flash(&flashTransport); -FatFileSystem fatfs; - - -void putPixels(uint8_t c, int32_t len) { - static uint8_t color; - uint8_t b = 0; - while(len--) { - b = 128; - for (int i=0; i<8; i++) { - if (c & b) { - color = WHITE; - } else { - color = BLACK; - } - b >>= 1; - if (color == BLACK) { - // we clear the buffer each frame so only black pixels need to be drawn - display.fillRect(X_OFFSET+curr_x*SCALE, Y_OFFSET+curr_y*SCALE, SCALE, SCALE, color); - } - curr_x++; - if(curr_x >= 128) { - curr_x = 0; - curr_y++; - if(curr_y >= 64) { - curr_y = 0; - display.refresh(); - display.clearDisplayBuffer(); - // 30 fps target rate - //if(digitalRead(0)) while((millis() - lastRefresh) < 33) ; - //lastRefresh = millis(); - } - } - } - } -} - -void decodeRLE(uint8_t c) { - if(c_to_dup == -1) { - if((c == 0x55) || (c == 0xaa)) { - c_to_dup = c; - } else { - putPixels(c, 1); - } - } else { - if(runlength == -1) { - if(c == 0) { - putPixels(c_to_dup & 0xff, 1); - c_to_dup = -1; - } else if((c & 0x80) == 0) { - if(c_to_dup == 0x55) { - putPixels(0, c); - } else { - putPixels(255, c); - } - c_to_dup = -1; - } else { - runlength = c & 0x7f; - } - } else { - runlength = runlength | (c << 7); - if(c_to_dup == 0x55) { - putPixels(0, runlength); - } else { - putPixels(255, runlength); - } - c_to_dup = -1; - runlength = -1; - } - } -} - -#define RLEBUFSIZE 4096 -#define READBUFSIZE 2048 -void readFile(const char * path){ - static uint8_t rle_buf[RLEBUFSIZE]; - size_t rle_bufhead = 0; - size_t rle_size = 0; - - size_t filelen = 0; - size_t filesize; - static uint8_t compbuf[READBUFSIZE]; - - Serial.printf("Reading file: %s\n", path); - File file = fatfs.open(path); - if(!file || file.isDirectory()){ - Serial.println("Failed to open file for reading"); - display.println("File open error. Upload video.hs using CircuitPython"); - display.refresh(); - return; - } - filelen = file.size(); - filesize = filelen; - Serial.printf("File size: %d\n", filelen); - - // init display, putPixels and decodeRLE - display.clearDisplay(); - display.refresh(); - curr_x = 0; - curr_y = 0; - runlength = -1; - c_to_dup = -1; - lastRefresh = millis(); - - // init decoder - heatshrink_decoder_reset(&hsd); - size_t count = 0; - uint32_t sunk = 0; - size_t toRead; - size_t toSink = 0; - uint32_t sinkHead = 0; - - - // Go through file... - while(filelen) { - if(toSink == 0) { - toRead = filelen; - if(toRead > READBUFSIZE) toRead = READBUFSIZE; - file.read(compbuf, toRead); - filelen -= toRead; - toSink = toRead; - sinkHead = 0; - } - - // uncompress buffer - HSD_sink_res sres; - sres = heatshrink_decoder_sink(&hsd, &compbuf[sinkHead], toSink, &count); - //Serial.print("^^ sinked "); - //Serial.println(count); - toSink -= count; - sinkHead = count; - sunk += count; - if (sunk == filesize) { - heatshrink_decoder_finish(&hsd); - } - - HSD_poll_res pres; - do { - rle_size = 0; - pres = heatshrink_decoder_poll(&hsd, rle_buf, RLEBUFSIZE, &rle_size); - //Serial.print("^^ polled "); - //Serial.println(rle_size); - if(pres < 0) { - Serial.print("POLL ERR! "); - Serial.println(pres); - return; - } - - rle_bufhead = 0; - while(rle_size) { - rle_size--; - if(rle_bufhead >= RLEBUFSIZE) { - Serial.println("RLE_SIZE ERR!"); - return; - } - decodeRLE(rle_buf[rle_bufhead++]); - } - } while (pres == HSDR_POLL_MORE); - } - file.close(); - Serial.println("Done."); -} - - - -void setup(){ - Serial.begin(115200); - //while (!Serial) delay(10); - Serial.println("Bad apple"); - - flash.begin(); - // Init file system on the flash - fatfs.begin(&flash); - - display.begin(); - display.clearDisplay(); - display.setTextColor(BLACK, WHITE); - display.setTextSize(2); - display.println("Scaled Bad Apple For SHARP Memory"); - display.refresh(); - - readFile("/video.hs"); -} - -void loop(){ - -} +// SPDX-FileCopyrightText: 2020 Melissa LeBlanc-Williams for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +// Bad Apple for ESP32 with OLED SSD1306 | 2018 by Hackerspace-FFM.de | MIT-License. +// Adapted for Sharp Memory display + Itsy Bitsy M4 - put video.hs on QSPI storage using CircuitPython +#include "heatshrink_decoder.h" + +#include "SdFat.h" +#include "Adafruit_SPIFlash.h" +#include +#define BLACK 0 +#define WHITE 1 + +#define SCALE 3 + + +#if HEATSHRINK_DYNAMIC_ALLOC +#error HEATSHRINK_DYNAMIC_ALLOC must be false for static allocation test suite. +#endif + +static heatshrink_decoder hsd; + +// global storage for putPixels +int16_t curr_x = 0; +int16_t curr_y = 0; + +// global storage for decodeRLE +int32_t runlength = -1; +int32_t c_to_dup = -1; + +uint32_t lastRefresh = 0; + +#define SHARP_SS A5 +Adafruit_SharpMem display(&SPI, SHARP_SS, 400, 240, 3000000); +#define X_OFFSET (400 - SCALE*128) / 2 +#define Y_OFFSET (240 - SCALE*64) / 2 + +Adafruit_FlashTransport_QSPI flashTransport; +Adafruit_SPIFlash flash(&flashTransport); +FatFileSystem fatfs; + + +void putPixels(uint8_t c, int32_t len) { + static uint8_t color; + uint8_t b = 0; + while(len--) { + b = 128; + for (int i=0; i<8; i++) { + if (c & b) { + color = WHITE; + } else { + color = BLACK; + } + b >>= 1; + if (color == BLACK) { + // we clear the buffer each frame so only black pixels need to be drawn + display.fillRect(X_OFFSET+curr_x*SCALE, Y_OFFSET+curr_y*SCALE, SCALE, SCALE, color); + } + curr_x++; + if(curr_x >= 128) { + curr_x = 0; + curr_y++; + if(curr_y >= 64) { + curr_y = 0; + display.refresh(); + display.clearDisplayBuffer(); + // 30 fps target rate + //if(digitalRead(0)) while((millis() - lastRefresh) < 33) ; + //lastRefresh = millis(); + } + } + } + } +} + +void decodeRLE(uint8_t c) { + if(c_to_dup == -1) { + if((c == 0x55) || (c == 0xaa)) { + c_to_dup = c; + } else { + putPixels(c, 1); + } + } else { + if(runlength == -1) { + if(c == 0) { + putPixels(c_to_dup & 0xff, 1); + c_to_dup = -1; + } else if((c & 0x80) == 0) { + if(c_to_dup == 0x55) { + putPixels(0, c); + } else { + putPixels(255, c); + } + c_to_dup = -1; + } else { + runlength = c & 0x7f; + } + } else { + runlength = runlength | (c << 7); + if(c_to_dup == 0x55) { + putPixels(0, runlength); + } else { + putPixels(255, runlength); + } + c_to_dup = -1; + runlength = -1; + } + } +} + +#define RLEBUFSIZE 4096 +#define READBUFSIZE 2048 +void readFile(const char * path){ + static uint8_t rle_buf[RLEBUFSIZE]; + size_t rle_bufhead = 0; + size_t rle_size = 0; + + size_t filelen = 0; + size_t filesize; + static uint8_t compbuf[READBUFSIZE]; + + Serial.printf("Reading file: %s\n", path); + File file = fatfs.open(path); + if(!file || file.isDirectory()){ + Serial.println("Failed to open file for reading"); + display.println("File open error. Upload video.hs using CircuitPython"); + display.refresh(); + return; + } + filelen = file.size(); + filesize = filelen; + Serial.printf("File size: %d\n", filelen); + + // init display, putPixels and decodeRLE + display.clearDisplay(); + display.refresh(); + curr_x = 0; + curr_y = 0; + runlength = -1; + c_to_dup = -1; + lastRefresh = millis(); + + // init decoder + heatshrink_decoder_reset(&hsd); + size_t count = 0; + uint32_t sunk = 0; + size_t toRead; + size_t toSink = 0; + uint32_t sinkHead = 0; + + + // Go through file... + while(filelen) { + if(toSink == 0) { + toRead = filelen; + if(toRead > READBUFSIZE) toRead = READBUFSIZE; + file.read(compbuf, toRead); + filelen -= toRead; + toSink = toRead; + sinkHead = 0; + } + + // uncompress buffer + HSD_sink_res sres; + sres = heatshrink_decoder_sink(&hsd, &compbuf[sinkHead], toSink, &count); + //Serial.print("^^ sinked "); + //Serial.println(count); + toSink -= count; + sinkHead = count; + sunk += count; + if (sunk == filesize) { + heatshrink_decoder_finish(&hsd); + } + + HSD_poll_res pres; + do { + rle_size = 0; + pres = heatshrink_decoder_poll(&hsd, rle_buf, RLEBUFSIZE, &rle_size); + //Serial.print("^^ polled "); + //Serial.println(rle_size); + if(pres < 0) { + Serial.print("POLL ERR! "); + Serial.println(pres); + return; + } + + rle_bufhead = 0; + while(rle_size) { + rle_size--; + if(rle_bufhead >= RLEBUFSIZE) { + Serial.println("RLE_SIZE ERR!"); + return; + } + decodeRLE(rle_buf[rle_bufhead++]); + } + } while (pres == HSDR_POLL_MORE); + } + file.close(); + Serial.println("Done."); +} + + + +void setup(){ + Serial.begin(115200); + //while (!Serial) delay(10); + Serial.println("Bad apple"); + + flash.begin(); + // Init file system on the flash + fatfs.begin(&flash); + + display.begin(); + display.clearDisplay(); + display.setTextColor(BLACK, WHITE); + display.setTextSize(2); + display.println("Scaled Bad Apple For SHARP Memory"); + display.refresh(); + + readFile("/video.hs"); +} + +void loop(){ + +} diff --git a/SHARP_BadApple/heatshrink_common.h b/SHARP_BadApple/heatshrink_common.h index 2d391fe1c..2e6a7ae5f 100755 --- a/SHARP_BadApple/heatshrink_common.h +++ b/SHARP_BadApple/heatshrink_common.h @@ -1,20 +1,24 @@ -#ifndef HEATSHRINK_H -#define HEATSHRINK_H - -#define HEATSHRINK_AUTHOR "Scott Vokes " -#define HEATSHRINK_URL "https://github.com/atomicobject/heatshrink" - -/* Version 0.4.1 */ -#define HEATSHRINK_VERSION_MAJOR 0 -#define HEATSHRINK_VERSION_MINOR 4 -#define HEATSHRINK_VERSION_PATCH 1 - -#define HEATSHRINK_MIN_WINDOW_BITS 4 -#define HEATSHRINK_MAX_WINDOW_BITS 15 - -#define HEATSHRINK_MIN_LOOKAHEAD_BITS 3 - -#define HEATSHRINK_LITERAL_MARKER 0x01 -#define HEATSHRINK_BACKREF_MARKER 0x00 - -#endif +// SPDX-FileCopyrightText: 2020 Melissa LeBlanc-Williams for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#ifndef HEATSHRINK_H +#define HEATSHRINK_H + +#define HEATSHRINK_AUTHOR "Scott Vokes " +#define HEATSHRINK_URL "https://github.com/atomicobject/heatshrink" + +/* Version 0.4.1 */ +#define HEATSHRINK_VERSION_MAJOR 0 +#define HEATSHRINK_VERSION_MINOR 4 +#define HEATSHRINK_VERSION_PATCH 1 + +#define HEATSHRINK_MIN_WINDOW_BITS 4 +#define HEATSHRINK_MAX_WINDOW_BITS 15 + +#define HEATSHRINK_MIN_LOOKAHEAD_BITS 3 + +#define HEATSHRINK_LITERAL_MARKER 0x01 +#define HEATSHRINK_BACKREF_MARKER 0x00 + +#endif diff --git a/SHARP_BadApple/heatshrink_config.h b/SHARP_BadApple/heatshrink_config.h index 14f3dfcfe..5d45facb9 100755 --- a/SHARP_BadApple/heatshrink_config.h +++ b/SHARP_BadApple/heatshrink_config.h @@ -1,26 +1,30 @@ -#ifndef HEATSHRINK_CONFIG_H -#define HEATSHRINK_CONFIG_H - -/* Should functionality assuming dynamic allocation be used? */ -#ifndef HEATSHRINK_DYNAMIC_ALLOC -#define HEATSHRINK_DYNAMIC_ALLOC 0 -#endif - -#if HEATSHRINK_DYNAMIC_ALLOC - /* Optional replacement of malloc/free */ - #define HEATSHRINK_MALLOC(SZ) malloc(SZ) - #define HEATSHRINK_FREE(P, SZ) free(P) -#else - /* Required parameters for static configuration */ - #define HEATSHRINK_STATIC_INPUT_BUFFER_SIZE 2048 - #define HEATSHRINK_STATIC_WINDOW_BITS 11 - #define HEATSHRINK_STATIC_LOOKAHEAD_BITS 4 -#endif - -/* Turn on logging for debugging. */ -#define HEATSHRINK_DEBUGGING_LOGS 0 - -/* Use indexing for faster compression. (This requires additional space.) */ -#define HEATSHRINK_USE_INDEX 1 - -#endif +// SPDX-FileCopyrightText: 2020 Melissa LeBlanc-Williams for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#ifndef HEATSHRINK_CONFIG_H +#define HEATSHRINK_CONFIG_H + +/* Should functionality assuming dynamic allocation be used? */ +#ifndef HEATSHRINK_DYNAMIC_ALLOC +#define HEATSHRINK_DYNAMIC_ALLOC 0 +#endif + +#if HEATSHRINK_DYNAMIC_ALLOC + /* Optional replacement of malloc/free */ + #define HEATSHRINK_MALLOC(SZ) malloc(SZ) + #define HEATSHRINK_FREE(P, SZ) free(P) +#else + /* Required parameters for static configuration */ + #define HEATSHRINK_STATIC_INPUT_BUFFER_SIZE 2048 + #define HEATSHRINK_STATIC_WINDOW_BITS 11 + #define HEATSHRINK_STATIC_LOOKAHEAD_BITS 4 +#endif + +/* Turn on logging for debugging. */ +#define HEATSHRINK_DEBUGGING_LOGS 0 + +/* Use indexing for faster compression. (This requires additional space.) */ +#define HEATSHRINK_USE_INDEX 1 + +#endif diff --git a/SHARP_BadApple/heatshrink_decoder.cpp b/SHARP_BadApple/heatshrink_decoder.cpp index ce5ed3ae3..84307d2f7 100755 --- a/SHARP_BadApple/heatshrink_decoder.cpp +++ b/SHARP_BadApple/heatshrink_decoder.cpp @@ -1,367 +1,371 @@ -#include -#include -#include "heatshrink_decoder.h" - -/* States for the polling state machine. */ -typedef enum { - HSDS_TAG_BIT, /* tag bit */ - HSDS_YIELD_LITERAL, /* ready to yield literal byte */ - HSDS_BACKREF_INDEX_MSB, /* most significant byte of index */ - HSDS_BACKREF_INDEX_LSB, /* least significant byte of index */ - HSDS_BACKREF_COUNT_MSB, /* most significant byte of count */ - HSDS_BACKREF_COUNT_LSB, /* least significant byte of count */ - HSDS_YIELD_BACKREF, /* ready to yield back-reference */ -} HSD_state; - -#if HEATSHRINK_DEBUGGING_LOGS -#include -#include -#include -#define LOG(...) fprintf(stderr, __VA_ARGS__) -#define ASSERT(X) assert(X) -static const char *state_names[] = { - "tag_bit", - "yield_literal", - "backref_index_msb", - "backref_index_lsb", - "backref_count_msb", - "backref_count_lsb", - "yield_backref", -}; -#else -#define LOG(...) /* no-op */ -#define ASSERT(X) /* no-op */ -#endif - -typedef struct { - uint8_t *buf; /* output buffer */ - size_t buf_size; /* buffer size */ - size_t *output_size; /* bytes pushed to buffer, so far */ -} output_info; - -#define NO_BITS ((uint16_t)-1) - -/* Forward references. */ -static uint16_t get_bits(heatshrink_decoder *hsd, uint8_t count); -static void push_byte(heatshrink_decoder *hsd, output_info *oi, uint8_t byte); - -#if HEATSHRINK_DYNAMIC_ALLOC -heatshrink_decoder *heatshrink_decoder_alloc(uint16_t input_buffer_size, - uint8_t window_sz2, - uint8_t lookahead_sz2) { - if ((window_sz2 < HEATSHRINK_MIN_WINDOW_BITS) || - (window_sz2 > HEATSHRINK_MAX_WINDOW_BITS) || - (input_buffer_size == 0) || - (lookahead_sz2 < HEATSHRINK_MIN_LOOKAHEAD_BITS) || - (lookahead_sz2 >= window_sz2)) { - return NULL; - } - size_t buffers_sz = (1 << window_sz2) + input_buffer_size; - size_t sz = sizeof(heatshrink_decoder) + buffers_sz; - heatshrink_decoder *hsd = HEATSHRINK_MALLOC(sz); - if (hsd == NULL) { return NULL; } - hsd->input_buffer_size = input_buffer_size; - hsd->window_sz2 = window_sz2; - hsd->lookahead_sz2 = lookahead_sz2; - heatshrink_decoder_reset(hsd); - LOG("-- allocated decoder with buffer size of %zu (%zu + %u + %u)\n", - sz, sizeof(heatshrink_decoder), (1 << window_sz2), input_buffer_size); - return hsd; -} - -void heatshrink_decoder_free(heatshrink_decoder *hsd) { - size_t buffers_sz = (1 << hsd->window_sz2) + hsd->input_buffer_size; - size_t sz = sizeof(heatshrink_decoder) + buffers_sz; - HEATSHRINK_FREE(hsd, sz); - (void)sz; /* may not be used by free */ -} -#endif - -void heatshrink_decoder_reset(heatshrink_decoder *hsd) { - size_t buf_sz = 1 << HEATSHRINK_DECODER_WINDOW_BITS(hsd); - size_t input_sz = HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(hsd); - memset(hsd->buffers, 0, buf_sz + input_sz); - hsd->state = HSDS_TAG_BIT; - hsd->input_size = 0; - hsd->input_index = 0; - hsd->bit_index = 0x00; - hsd->current_byte = 0x00; - hsd->output_count = 0; - hsd->output_index = 0; - hsd->head_index = 0; -} - -/* Copy SIZE bytes into the decoder's input buffer, if it will fit. */ -HSD_sink_res heatshrink_decoder_sink(heatshrink_decoder *hsd, - uint8_t *in_buf, size_t size, size_t *input_size) { - if ((hsd == NULL) || (in_buf == NULL) || (input_size == NULL)) { - return HSDR_SINK_ERROR_NULL; - } - - size_t rem = HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(hsd) - hsd->input_size; - if (rem == 0) { - *input_size = 0; - return HSDR_SINK_FULL; - } - - size = rem < size ? rem : size; - LOG("-- sinking %zd bytes\n", size); - /* copy into input buffer (at head of buffers) */ - memcpy(&hsd->buffers[hsd->input_size], in_buf, size); - hsd->input_size += size; - *input_size = size; - return HSDR_SINK_OK; -} - - -/***************** - * Decompression * - *****************/ - -#define BACKREF_COUNT_BITS(HSD) (HEATSHRINK_DECODER_LOOKAHEAD_BITS(HSD)) -#define BACKREF_INDEX_BITS(HSD) (HEATSHRINK_DECODER_WINDOW_BITS(HSD)) - -// States -static HSD_state st_tag_bit(heatshrink_decoder *hsd); -static HSD_state st_yield_literal(heatshrink_decoder *hsd, - output_info *oi); -static HSD_state st_backref_index_msb(heatshrink_decoder *hsd); -static HSD_state st_backref_index_lsb(heatshrink_decoder *hsd); -static HSD_state st_backref_count_msb(heatshrink_decoder *hsd); -static HSD_state st_backref_count_lsb(heatshrink_decoder *hsd); -static HSD_state st_yield_backref(heatshrink_decoder *hsd, - output_info *oi); - -HSD_poll_res heatshrink_decoder_poll(heatshrink_decoder *hsd, - uint8_t *out_buf, size_t out_buf_size, size_t *output_size) { - if ((hsd == NULL) || (out_buf == NULL) || (output_size == NULL)) { - return HSDR_POLL_ERROR_NULL; - } - *output_size = 0; - - output_info oi; - oi.buf = out_buf; - oi.buf_size = out_buf_size; - oi.output_size = output_size; - - while (1) { - LOG("-- poll, state is %d (%s), input_size %d\n", - hsd->state, state_names[hsd->state], hsd->input_size); - uint8_t in_state = hsd->state; - switch (in_state) { - case HSDS_TAG_BIT: - hsd->state = st_tag_bit(hsd); - break; - case HSDS_YIELD_LITERAL: - hsd->state = st_yield_literal(hsd, &oi); - break; - case HSDS_BACKREF_INDEX_MSB: - hsd->state = st_backref_index_msb(hsd); - break; - case HSDS_BACKREF_INDEX_LSB: - hsd->state = st_backref_index_lsb(hsd); - break; - case HSDS_BACKREF_COUNT_MSB: - hsd->state = st_backref_count_msb(hsd); - break; - case HSDS_BACKREF_COUNT_LSB: - hsd->state = st_backref_count_lsb(hsd); - break; - case HSDS_YIELD_BACKREF: - hsd->state = st_yield_backref(hsd, &oi); - break; - default: - return HSDR_POLL_ERROR_UNKNOWN; - } - - /* If the current state cannot advance, check if input or output - * buffer are exhausted. */ - if (hsd->state == in_state) { - if (*output_size == out_buf_size) { return HSDR_POLL_MORE; } - return HSDR_POLL_EMPTY; - } - } -} - -static HSD_state st_tag_bit(heatshrink_decoder *hsd) { - uint32_t bits = get_bits(hsd, 1); // get tag bit - if (bits == NO_BITS) { - return HSDS_TAG_BIT; - } else if (bits) { - return HSDS_YIELD_LITERAL; - } else if (HEATSHRINK_DECODER_WINDOW_BITS(hsd) > 8) { - return HSDS_BACKREF_INDEX_MSB; - } else { - hsd->output_index = 0; - return HSDS_BACKREF_INDEX_LSB; - } -} - -static HSD_state st_yield_literal(heatshrink_decoder *hsd, - output_info *oi) { - /* Emit a repeated section from the window buffer, and add it (again) - * to the window buffer. (Note that the repetition can include - * itself.)*/ - if (*oi->output_size < oi->buf_size) { - uint16_t byte = get_bits(hsd, 8); - if (byte == NO_BITS) { return HSDS_YIELD_LITERAL; } /* out of input */ - uint8_t *buf = &hsd->buffers[HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(hsd)]; - uint16_t mask = (1 << HEATSHRINK_DECODER_WINDOW_BITS(hsd)) - 1; - uint8_t c = byte & 0xFF; - LOG("-- emitting literal byte 0x%02x ('%c')\n", c, isprint(c) ? c : '.'); - buf[hsd->head_index++ & mask] = c; - push_byte(hsd, oi, c); - return HSDS_TAG_BIT; - } else { - return HSDS_YIELD_LITERAL; - } -} - -static HSD_state st_backref_index_msb(heatshrink_decoder *hsd) { - uint8_t bit_ct = BACKREF_INDEX_BITS(hsd); - ASSERT(bit_ct > 8); - uint16_t bits = get_bits(hsd, bit_ct - 8); - LOG("-- backref index (msb), got 0x%04x (+1)\n", bits); - if (bits == NO_BITS) { return HSDS_BACKREF_INDEX_MSB; } - hsd->output_index = bits << 8; - return HSDS_BACKREF_INDEX_LSB; -} - -static HSD_state st_backref_index_lsb(heatshrink_decoder *hsd) { - uint8_t bit_ct = BACKREF_INDEX_BITS(hsd); - uint16_t bits = get_bits(hsd, bit_ct < 8 ? bit_ct : 8); - LOG("-- backref index (lsb), got 0x%04x (+1)\n", bits); - if (bits == NO_BITS) { return HSDS_BACKREF_INDEX_LSB; } - hsd->output_index |= bits; - hsd->output_index++; - uint8_t br_bit_ct = BACKREF_COUNT_BITS(hsd); - hsd->output_count = 0; - return (br_bit_ct > 8) ? HSDS_BACKREF_COUNT_MSB : HSDS_BACKREF_COUNT_LSB; -} - -static HSD_state st_backref_count_msb(heatshrink_decoder *hsd) { - uint8_t br_bit_ct = BACKREF_COUNT_BITS(hsd); - ASSERT(br_bit_ct > 8); - uint16_t bits = get_bits(hsd, br_bit_ct - 8); - LOG("-- backref count (msb), got 0x%04x (+1)\n", bits); - if (bits == NO_BITS) { return HSDS_BACKREF_COUNT_MSB; } - hsd->output_count = bits << 8; - return HSDS_BACKREF_COUNT_LSB; -} - -static HSD_state st_backref_count_lsb(heatshrink_decoder *hsd) { - uint8_t br_bit_ct = BACKREF_COUNT_BITS(hsd); - uint16_t bits = get_bits(hsd, br_bit_ct < 8 ? br_bit_ct : 8); - LOG("-- backref count (lsb), got 0x%04x (+1)\n", bits); - if (bits == NO_BITS) { return HSDS_BACKREF_COUNT_LSB; } - hsd->output_count |= bits; - hsd->output_count++; - return HSDS_YIELD_BACKREF; -} - -static HSD_state st_yield_backref(heatshrink_decoder *hsd, - output_info *oi) { - size_t count = oi->buf_size - *oi->output_size; - if (count > 0) { - size_t i = 0; - if (hsd->output_count < count) count = hsd->output_count; - uint8_t *buf = &hsd->buffers[HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(hsd)]; - uint16_t mask = (1 << HEATSHRINK_DECODER_WINDOW_BITS(hsd)) - 1; - uint16_t neg_offset = hsd->output_index; - LOG("-- emitting %zu bytes from -%u bytes back\n", count, neg_offset); - ASSERT(neg_offset <= mask + 1); - ASSERT(count <= (size_t)(1 << BACKREF_COUNT_BITS(hsd))); - - for (i=0; ihead_index - neg_offset) & mask]; - push_byte(hsd, oi, c); - buf[hsd->head_index & mask] = c; - hsd->head_index++; - LOG(" -- ++ 0x%02x\n", c); - } - hsd->output_count -= count; - if (hsd->output_count == 0) { return HSDS_TAG_BIT; } - } - return HSDS_YIELD_BACKREF; -} - -/* Get the next COUNT bits from the input buffer, saving incremental progress. - * Returns NO_BITS on end of input, or if more than 15 bits are requested. */ -static uint16_t get_bits(heatshrink_decoder *hsd, uint8_t count) { - uint16_t accumulator = 0; - int i = 0; - if (count > 15) { return NO_BITS; } - LOG("-- popping %u bit(s)\n", count); - - /* If we aren't able to get COUNT bits, suspend immediately, because we - * don't track how many bits of COUNT we've accumulated before suspend. */ - if (hsd->input_size == 0) { - if (hsd->bit_index < (1 << (count - 1))) { return NO_BITS; } - } - - for (i = 0; i < count; i++) { - if (hsd->bit_index == 0x00) { - if (hsd->input_size == 0) { - LOG(" -- out of bits, suspending w/ accumulator of %u (0x%02x)\n", - accumulator, accumulator); - return NO_BITS; - } - hsd->current_byte = hsd->buffers[hsd->input_index++]; - LOG(" -- pulled byte 0x%02x\n", hsd->current_byte); - if (hsd->input_index == hsd->input_size) { - hsd->input_index = 0; /* input is exhausted */ - hsd->input_size = 0; - } - hsd->bit_index = 0x80; - } - accumulator <<= 1; - if (hsd->current_byte & hsd->bit_index) { - accumulator |= 0x01; - if (0) { - LOG(" -- got 1, accumulator 0x%04x, bit_index 0x%02x\n", - accumulator, hsd->bit_index); - } - } else { - if (0) { - LOG(" -- got 0, accumulator 0x%04x, bit_index 0x%02x\n", - accumulator, hsd->bit_index); - } - } - hsd->bit_index >>= 1; - } - - if (count > 1) { LOG(" -- accumulated %08x\n", accumulator); } - return accumulator; -} - -HSD_finish_res heatshrink_decoder_finish(heatshrink_decoder *hsd) { - if (hsd == NULL) { return HSDR_FINISH_ERROR_NULL; } - switch (hsd->state) { - case HSDS_TAG_BIT: - return hsd->input_size == 0 ? HSDR_FINISH_DONE : HSDR_FINISH_MORE; - - /* If we want to finish with no input, but are in these states, it's - * because the 0-bit padding to the last byte looks like a backref - * marker bit followed by all 0s for index and count bits. */ - case HSDS_BACKREF_INDEX_LSB: - case HSDS_BACKREF_INDEX_MSB: - case HSDS_BACKREF_COUNT_LSB: - case HSDS_BACKREF_COUNT_MSB: - return hsd->input_size == 0 ? HSDR_FINISH_DONE : HSDR_FINISH_MORE; - - /* If the output stream is padded with 0xFFs (possibly due to being in - * flash memory), also explicitly check the input size rather than - * uselessly returning MORE but yielding 0 bytes when polling. */ - case HSDS_YIELD_LITERAL: - return hsd->input_size == 0 ? HSDR_FINISH_DONE : HSDR_FINISH_MORE; - - default: - return HSDR_FINISH_MORE; - } -} - -static void push_byte(heatshrink_decoder *hsd, output_info *oi, uint8_t byte) { - LOG(" -- pushing byte: 0x%02x ('%c')\n", byte, isprint(byte) ? byte : '.'); - oi->buf[(*oi->output_size)++] = byte; - (void)hsd; -} +// SPDX-FileCopyrightText: 2020 Melissa LeBlanc-Williams for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include +#include +#include "heatshrink_decoder.h" + +/* States for the polling state machine. */ +typedef enum { + HSDS_TAG_BIT, /* tag bit */ + HSDS_YIELD_LITERAL, /* ready to yield literal byte */ + HSDS_BACKREF_INDEX_MSB, /* most significant byte of index */ + HSDS_BACKREF_INDEX_LSB, /* least significant byte of index */ + HSDS_BACKREF_COUNT_MSB, /* most significant byte of count */ + HSDS_BACKREF_COUNT_LSB, /* least significant byte of count */ + HSDS_YIELD_BACKREF, /* ready to yield back-reference */ +} HSD_state; + +#if HEATSHRINK_DEBUGGING_LOGS +#include +#include +#include +#define LOG(...) fprintf(stderr, __VA_ARGS__) +#define ASSERT(X) assert(X) +static const char *state_names[] = { + "tag_bit", + "yield_literal", + "backref_index_msb", + "backref_index_lsb", + "backref_count_msb", + "backref_count_lsb", + "yield_backref", +}; +#else +#define LOG(...) /* no-op */ +#define ASSERT(X) /* no-op */ +#endif + +typedef struct { + uint8_t *buf; /* output buffer */ + size_t buf_size; /* buffer size */ + size_t *output_size; /* bytes pushed to buffer, so far */ +} output_info; + +#define NO_BITS ((uint16_t)-1) + +/* Forward references. */ +static uint16_t get_bits(heatshrink_decoder *hsd, uint8_t count); +static void push_byte(heatshrink_decoder *hsd, output_info *oi, uint8_t byte); + +#if HEATSHRINK_DYNAMIC_ALLOC +heatshrink_decoder *heatshrink_decoder_alloc(uint16_t input_buffer_size, + uint8_t window_sz2, + uint8_t lookahead_sz2) { + if ((window_sz2 < HEATSHRINK_MIN_WINDOW_BITS) || + (window_sz2 > HEATSHRINK_MAX_WINDOW_BITS) || + (input_buffer_size == 0) || + (lookahead_sz2 < HEATSHRINK_MIN_LOOKAHEAD_BITS) || + (lookahead_sz2 >= window_sz2)) { + return NULL; + } + size_t buffers_sz = (1 << window_sz2) + input_buffer_size; + size_t sz = sizeof(heatshrink_decoder) + buffers_sz; + heatshrink_decoder *hsd = HEATSHRINK_MALLOC(sz); + if (hsd == NULL) { return NULL; } + hsd->input_buffer_size = input_buffer_size; + hsd->window_sz2 = window_sz2; + hsd->lookahead_sz2 = lookahead_sz2; + heatshrink_decoder_reset(hsd); + LOG("-- allocated decoder with buffer size of %zu (%zu + %u + %u)\n", + sz, sizeof(heatshrink_decoder), (1 << window_sz2), input_buffer_size); + return hsd; +} + +void heatshrink_decoder_free(heatshrink_decoder *hsd) { + size_t buffers_sz = (1 << hsd->window_sz2) + hsd->input_buffer_size; + size_t sz = sizeof(heatshrink_decoder) + buffers_sz; + HEATSHRINK_FREE(hsd, sz); + (void)sz; /* may not be used by free */ +} +#endif + +void heatshrink_decoder_reset(heatshrink_decoder *hsd) { + size_t buf_sz = 1 << HEATSHRINK_DECODER_WINDOW_BITS(hsd); + size_t input_sz = HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(hsd); + memset(hsd->buffers, 0, buf_sz + input_sz); + hsd->state = HSDS_TAG_BIT; + hsd->input_size = 0; + hsd->input_index = 0; + hsd->bit_index = 0x00; + hsd->current_byte = 0x00; + hsd->output_count = 0; + hsd->output_index = 0; + hsd->head_index = 0; +} + +/* Copy SIZE bytes into the decoder's input buffer, if it will fit. */ +HSD_sink_res heatshrink_decoder_sink(heatshrink_decoder *hsd, + uint8_t *in_buf, size_t size, size_t *input_size) { + if ((hsd == NULL) || (in_buf == NULL) || (input_size == NULL)) { + return HSDR_SINK_ERROR_NULL; + } + + size_t rem = HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(hsd) - hsd->input_size; + if (rem == 0) { + *input_size = 0; + return HSDR_SINK_FULL; + } + + size = rem < size ? rem : size; + LOG("-- sinking %zd bytes\n", size); + /* copy into input buffer (at head of buffers) */ + memcpy(&hsd->buffers[hsd->input_size], in_buf, size); + hsd->input_size += size; + *input_size = size; + return HSDR_SINK_OK; +} + + +/***************** + * Decompression * + *****************/ + +#define BACKREF_COUNT_BITS(HSD) (HEATSHRINK_DECODER_LOOKAHEAD_BITS(HSD)) +#define BACKREF_INDEX_BITS(HSD) (HEATSHRINK_DECODER_WINDOW_BITS(HSD)) + +// States +static HSD_state st_tag_bit(heatshrink_decoder *hsd); +static HSD_state st_yield_literal(heatshrink_decoder *hsd, + output_info *oi); +static HSD_state st_backref_index_msb(heatshrink_decoder *hsd); +static HSD_state st_backref_index_lsb(heatshrink_decoder *hsd); +static HSD_state st_backref_count_msb(heatshrink_decoder *hsd); +static HSD_state st_backref_count_lsb(heatshrink_decoder *hsd); +static HSD_state st_yield_backref(heatshrink_decoder *hsd, + output_info *oi); + +HSD_poll_res heatshrink_decoder_poll(heatshrink_decoder *hsd, + uint8_t *out_buf, size_t out_buf_size, size_t *output_size) { + if ((hsd == NULL) || (out_buf == NULL) || (output_size == NULL)) { + return HSDR_POLL_ERROR_NULL; + } + *output_size = 0; + + output_info oi; + oi.buf = out_buf; + oi.buf_size = out_buf_size; + oi.output_size = output_size; + + while (1) { + LOG("-- poll, state is %d (%s), input_size %d\n", + hsd->state, state_names[hsd->state], hsd->input_size); + uint8_t in_state = hsd->state; + switch (in_state) { + case HSDS_TAG_BIT: + hsd->state = st_tag_bit(hsd); + break; + case HSDS_YIELD_LITERAL: + hsd->state = st_yield_literal(hsd, &oi); + break; + case HSDS_BACKREF_INDEX_MSB: + hsd->state = st_backref_index_msb(hsd); + break; + case HSDS_BACKREF_INDEX_LSB: + hsd->state = st_backref_index_lsb(hsd); + break; + case HSDS_BACKREF_COUNT_MSB: + hsd->state = st_backref_count_msb(hsd); + break; + case HSDS_BACKREF_COUNT_LSB: + hsd->state = st_backref_count_lsb(hsd); + break; + case HSDS_YIELD_BACKREF: + hsd->state = st_yield_backref(hsd, &oi); + break; + default: + return HSDR_POLL_ERROR_UNKNOWN; + } + + /* If the current state cannot advance, check if input or output + * buffer are exhausted. */ + if (hsd->state == in_state) { + if (*output_size == out_buf_size) { return HSDR_POLL_MORE; } + return HSDR_POLL_EMPTY; + } + } +} + +static HSD_state st_tag_bit(heatshrink_decoder *hsd) { + uint32_t bits = get_bits(hsd, 1); // get tag bit + if (bits == NO_BITS) { + return HSDS_TAG_BIT; + } else if (bits) { + return HSDS_YIELD_LITERAL; + } else if (HEATSHRINK_DECODER_WINDOW_BITS(hsd) > 8) { + return HSDS_BACKREF_INDEX_MSB; + } else { + hsd->output_index = 0; + return HSDS_BACKREF_INDEX_LSB; + } +} + +static HSD_state st_yield_literal(heatshrink_decoder *hsd, + output_info *oi) { + /* Emit a repeated section from the window buffer, and add it (again) + * to the window buffer. (Note that the repetition can include + * itself.)*/ + if (*oi->output_size < oi->buf_size) { + uint16_t byte = get_bits(hsd, 8); + if (byte == NO_BITS) { return HSDS_YIELD_LITERAL; } /* out of input */ + uint8_t *buf = &hsd->buffers[HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(hsd)]; + uint16_t mask = (1 << HEATSHRINK_DECODER_WINDOW_BITS(hsd)) - 1; + uint8_t c = byte & 0xFF; + LOG("-- emitting literal byte 0x%02x ('%c')\n", c, isprint(c) ? c : '.'); + buf[hsd->head_index++ & mask] = c; + push_byte(hsd, oi, c); + return HSDS_TAG_BIT; + } else { + return HSDS_YIELD_LITERAL; + } +} + +static HSD_state st_backref_index_msb(heatshrink_decoder *hsd) { + uint8_t bit_ct = BACKREF_INDEX_BITS(hsd); + ASSERT(bit_ct > 8); + uint16_t bits = get_bits(hsd, bit_ct - 8); + LOG("-- backref index (msb), got 0x%04x (+1)\n", bits); + if (bits == NO_BITS) { return HSDS_BACKREF_INDEX_MSB; } + hsd->output_index = bits << 8; + return HSDS_BACKREF_INDEX_LSB; +} + +static HSD_state st_backref_index_lsb(heatshrink_decoder *hsd) { + uint8_t bit_ct = BACKREF_INDEX_BITS(hsd); + uint16_t bits = get_bits(hsd, bit_ct < 8 ? bit_ct : 8); + LOG("-- backref index (lsb), got 0x%04x (+1)\n", bits); + if (bits == NO_BITS) { return HSDS_BACKREF_INDEX_LSB; } + hsd->output_index |= bits; + hsd->output_index++; + uint8_t br_bit_ct = BACKREF_COUNT_BITS(hsd); + hsd->output_count = 0; + return (br_bit_ct > 8) ? HSDS_BACKREF_COUNT_MSB : HSDS_BACKREF_COUNT_LSB; +} + +static HSD_state st_backref_count_msb(heatshrink_decoder *hsd) { + uint8_t br_bit_ct = BACKREF_COUNT_BITS(hsd); + ASSERT(br_bit_ct > 8); + uint16_t bits = get_bits(hsd, br_bit_ct - 8); + LOG("-- backref count (msb), got 0x%04x (+1)\n", bits); + if (bits == NO_BITS) { return HSDS_BACKREF_COUNT_MSB; } + hsd->output_count = bits << 8; + return HSDS_BACKREF_COUNT_LSB; +} + +static HSD_state st_backref_count_lsb(heatshrink_decoder *hsd) { + uint8_t br_bit_ct = BACKREF_COUNT_BITS(hsd); + uint16_t bits = get_bits(hsd, br_bit_ct < 8 ? br_bit_ct : 8); + LOG("-- backref count (lsb), got 0x%04x (+1)\n", bits); + if (bits == NO_BITS) { return HSDS_BACKREF_COUNT_LSB; } + hsd->output_count |= bits; + hsd->output_count++; + return HSDS_YIELD_BACKREF; +} + +static HSD_state st_yield_backref(heatshrink_decoder *hsd, + output_info *oi) { + size_t count = oi->buf_size - *oi->output_size; + if (count > 0) { + size_t i = 0; + if (hsd->output_count < count) count = hsd->output_count; + uint8_t *buf = &hsd->buffers[HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(hsd)]; + uint16_t mask = (1 << HEATSHRINK_DECODER_WINDOW_BITS(hsd)) - 1; + uint16_t neg_offset = hsd->output_index; + LOG("-- emitting %zu bytes from -%u bytes back\n", count, neg_offset); + ASSERT(neg_offset <= mask + 1); + ASSERT(count <= (size_t)(1 << BACKREF_COUNT_BITS(hsd))); + + for (i=0; ihead_index - neg_offset) & mask]; + push_byte(hsd, oi, c); + buf[hsd->head_index & mask] = c; + hsd->head_index++; + LOG(" -- ++ 0x%02x\n", c); + } + hsd->output_count -= count; + if (hsd->output_count == 0) { return HSDS_TAG_BIT; } + } + return HSDS_YIELD_BACKREF; +} + +/* Get the next COUNT bits from the input buffer, saving incremental progress. + * Returns NO_BITS on end of input, or if more than 15 bits are requested. */ +static uint16_t get_bits(heatshrink_decoder *hsd, uint8_t count) { + uint16_t accumulator = 0; + int i = 0; + if (count > 15) { return NO_BITS; } + LOG("-- popping %u bit(s)\n", count); + + /* If we aren't able to get COUNT bits, suspend immediately, because we + * don't track how many bits of COUNT we've accumulated before suspend. */ + if (hsd->input_size == 0) { + if (hsd->bit_index < (1 << (count - 1))) { return NO_BITS; } + } + + for (i = 0; i < count; i++) { + if (hsd->bit_index == 0x00) { + if (hsd->input_size == 0) { + LOG(" -- out of bits, suspending w/ accumulator of %u (0x%02x)\n", + accumulator, accumulator); + return NO_BITS; + } + hsd->current_byte = hsd->buffers[hsd->input_index++]; + LOG(" -- pulled byte 0x%02x\n", hsd->current_byte); + if (hsd->input_index == hsd->input_size) { + hsd->input_index = 0; /* input is exhausted */ + hsd->input_size = 0; + } + hsd->bit_index = 0x80; + } + accumulator <<= 1; + if (hsd->current_byte & hsd->bit_index) { + accumulator |= 0x01; + if (0) { + LOG(" -- got 1, accumulator 0x%04x, bit_index 0x%02x\n", + accumulator, hsd->bit_index); + } + } else { + if (0) { + LOG(" -- got 0, accumulator 0x%04x, bit_index 0x%02x\n", + accumulator, hsd->bit_index); + } + } + hsd->bit_index >>= 1; + } + + if (count > 1) { LOG(" -- accumulated %08x\n", accumulator); } + return accumulator; +} + +HSD_finish_res heatshrink_decoder_finish(heatshrink_decoder *hsd) { + if (hsd == NULL) { return HSDR_FINISH_ERROR_NULL; } + switch (hsd->state) { + case HSDS_TAG_BIT: + return hsd->input_size == 0 ? HSDR_FINISH_DONE : HSDR_FINISH_MORE; + + /* If we want to finish with no input, but are in these states, it's + * because the 0-bit padding to the last byte looks like a backref + * marker bit followed by all 0s for index and count bits. */ + case HSDS_BACKREF_INDEX_LSB: + case HSDS_BACKREF_INDEX_MSB: + case HSDS_BACKREF_COUNT_LSB: + case HSDS_BACKREF_COUNT_MSB: + return hsd->input_size == 0 ? HSDR_FINISH_DONE : HSDR_FINISH_MORE; + + /* If the output stream is padded with 0xFFs (possibly due to being in + * flash memory), also explicitly check the input size rather than + * uselessly returning MORE but yielding 0 bytes when polling. */ + case HSDS_YIELD_LITERAL: + return hsd->input_size == 0 ? HSDR_FINISH_DONE : HSDR_FINISH_MORE; + + default: + return HSDR_FINISH_MORE; + } +} + +static void push_byte(heatshrink_decoder *hsd, output_info *oi, uint8_t byte) { + LOG(" -- pushing byte: 0x%02x ('%c')\n", byte, isprint(byte) ? byte : '.'); + oi->buf[(*oi->output_size)++] = byte; + (void)hsd; +} diff --git a/SHARP_BadApple/heatshrink_decoder.h b/SHARP_BadApple/heatshrink_decoder.h index dbcd4c866..a11ca87bb 100755 --- a/SHARP_BadApple/heatshrink_decoder.h +++ b/SHARP_BadApple/heatshrink_decoder.h @@ -1,100 +1,104 @@ -#ifndef HEATSHRINK_DECODER_H -#define HEATSHRINK_DECODER_H - -#include -#include -#include "heatshrink_common.h" -#include "heatshrink_config.h" - -typedef enum { - HSDR_SINK_OK, /* data sunk, ready to poll */ - HSDR_SINK_FULL, /* out of space in internal buffer */ - HSDR_SINK_ERROR_NULL=-1, /* NULL argument */ -} HSD_sink_res; - -typedef enum { - HSDR_POLL_EMPTY, /* input exhausted */ - HSDR_POLL_MORE, /* more data remaining, call again w/ fresh output buffer */ - HSDR_POLL_ERROR_NULL=-1, /* NULL arguments */ - HSDR_POLL_ERROR_UNKNOWN=-2, -} HSD_poll_res; - -typedef enum { - HSDR_FINISH_DONE, /* output is done */ - HSDR_FINISH_MORE, /* more output remains */ - HSDR_FINISH_ERROR_NULL=-1, /* NULL arguments */ -} HSD_finish_res; - -#if HEATSHRINK_DYNAMIC_ALLOC -#define HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(BUF) \ - ((BUF)->input_buffer_size) -#define HEATSHRINK_DECODER_WINDOW_BITS(BUF) \ - ((BUF)->window_sz2) -#define HEATSHRINK_DECODER_LOOKAHEAD_BITS(BUF) \ - ((BUF)->lookahead_sz2) -#else -#define HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(_) \ - HEATSHRINK_STATIC_INPUT_BUFFER_SIZE -#define HEATSHRINK_DECODER_WINDOW_BITS(_) \ - (HEATSHRINK_STATIC_WINDOW_BITS) -#define HEATSHRINK_DECODER_LOOKAHEAD_BITS(BUF) \ - (HEATSHRINK_STATIC_LOOKAHEAD_BITS) -#endif - -typedef struct { - uint16_t input_size; /* bytes in input buffer */ - uint16_t input_index; /* offset to next unprocessed input byte */ - uint16_t output_count; /* how many bytes to output */ - uint16_t output_index; /* index for bytes to output */ - uint16_t head_index; /* head of window buffer */ - uint8_t state; /* current state machine node */ - uint8_t current_byte; /* current byte of input */ - uint8_t bit_index; /* current bit index */ - -#if HEATSHRINK_DYNAMIC_ALLOC - /* Fields that are only used if dynamically allocated. */ - uint8_t window_sz2; /* window buffer bits */ - uint8_t lookahead_sz2; /* lookahead bits */ - uint16_t input_buffer_size; /* input buffer size */ - - /* Input buffer, then expansion window buffer */ - uint8_t buffers[]; -#else - /* Input buffer, then expansion window buffer */ - uint8_t buffers[(1 << HEATSHRINK_DECODER_WINDOW_BITS(_)) - + HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(_)]; -#endif -} heatshrink_decoder; - -#if HEATSHRINK_DYNAMIC_ALLOC -/* Allocate a decoder with an input buffer of INPUT_BUFFER_SIZE bytes, - * an expansion buffer size of 2^WINDOW_SZ2, and a lookahead - * size of 2^lookahead_sz2. (The window buffer and lookahead sizes - * must match the settings used when the data was compressed.) - * Returns NULL on error. */ -heatshrink_decoder *heatshrink_decoder_alloc(uint16_t input_buffer_size, - uint8_t expansion_buffer_sz2, uint8_t lookahead_sz2); - -/* Free a decoder. */ -void heatshrink_decoder_free(heatshrink_decoder *hsd); -#endif - -/* Reset a decoder. */ -void heatshrink_decoder_reset(heatshrink_decoder *hsd); - -/* Sink at most SIZE bytes from IN_BUF into the decoder. *INPUT_SIZE is set to - * indicate how many bytes were actually sunk (in case a buffer was filled). */ -HSD_sink_res heatshrink_decoder_sink(heatshrink_decoder *hsd, - uint8_t *in_buf, size_t size, size_t *input_size); - -/* Poll for output from the decoder, copying at most OUT_BUF_SIZE bytes into - * OUT_BUF (setting *OUTPUT_SIZE to the actual amount copied). */ -HSD_poll_res heatshrink_decoder_poll(heatshrink_decoder *hsd, - uint8_t *out_buf, size_t out_buf_size, size_t *output_size); - -/* Notify the dencoder that the input stream is finished. - * If the return value is HSDR_FINISH_MORE, there is still more output, so - * call heatshrink_decoder_poll and repeat. */ -HSD_finish_res heatshrink_decoder_finish(heatshrink_decoder *hsd); - -#endif +// SPDX-FileCopyrightText: 2020 Melissa LeBlanc-Williams for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#ifndef HEATSHRINK_DECODER_H +#define HEATSHRINK_DECODER_H + +#include +#include +#include "heatshrink_common.h" +#include "heatshrink_config.h" + +typedef enum { + HSDR_SINK_OK, /* data sunk, ready to poll */ + HSDR_SINK_FULL, /* out of space in internal buffer */ + HSDR_SINK_ERROR_NULL=-1, /* NULL argument */ +} HSD_sink_res; + +typedef enum { + HSDR_POLL_EMPTY, /* input exhausted */ + HSDR_POLL_MORE, /* more data remaining, call again w/ fresh output buffer */ + HSDR_POLL_ERROR_NULL=-1, /* NULL arguments */ + HSDR_POLL_ERROR_UNKNOWN=-2, +} HSD_poll_res; + +typedef enum { + HSDR_FINISH_DONE, /* output is done */ + HSDR_FINISH_MORE, /* more output remains */ + HSDR_FINISH_ERROR_NULL=-1, /* NULL arguments */ +} HSD_finish_res; + +#if HEATSHRINK_DYNAMIC_ALLOC +#define HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(BUF) \ + ((BUF)->input_buffer_size) +#define HEATSHRINK_DECODER_WINDOW_BITS(BUF) \ + ((BUF)->window_sz2) +#define HEATSHRINK_DECODER_LOOKAHEAD_BITS(BUF) \ + ((BUF)->lookahead_sz2) +#else +#define HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(_) \ + HEATSHRINK_STATIC_INPUT_BUFFER_SIZE +#define HEATSHRINK_DECODER_WINDOW_BITS(_) \ + (HEATSHRINK_STATIC_WINDOW_BITS) +#define HEATSHRINK_DECODER_LOOKAHEAD_BITS(BUF) \ + (HEATSHRINK_STATIC_LOOKAHEAD_BITS) +#endif + +typedef struct { + uint16_t input_size; /* bytes in input buffer */ + uint16_t input_index; /* offset to next unprocessed input byte */ + uint16_t output_count; /* how many bytes to output */ + uint16_t output_index; /* index for bytes to output */ + uint16_t head_index; /* head of window buffer */ + uint8_t state; /* current state machine node */ + uint8_t current_byte; /* current byte of input */ + uint8_t bit_index; /* current bit index */ + +#if HEATSHRINK_DYNAMIC_ALLOC + /* Fields that are only used if dynamically allocated. */ + uint8_t window_sz2; /* window buffer bits */ + uint8_t lookahead_sz2; /* lookahead bits */ + uint16_t input_buffer_size; /* input buffer size */ + + /* Input buffer, then expansion window buffer */ + uint8_t buffers[]; +#else + /* Input buffer, then expansion window buffer */ + uint8_t buffers[(1 << HEATSHRINK_DECODER_WINDOW_BITS(_)) + + HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(_)]; +#endif +} heatshrink_decoder; + +#if HEATSHRINK_DYNAMIC_ALLOC +/* Allocate a decoder with an input buffer of INPUT_BUFFER_SIZE bytes, + * an expansion buffer size of 2^WINDOW_SZ2, and a lookahead + * size of 2^lookahead_sz2. (The window buffer and lookahead sizes + * must match the settings used when the data was compressed.) + * Returns NULL on error. */ +heatshrink_decoder *heatshrink_decoder_alloc(uint16_t input_buffer_size, + uint8_t expansion_buffer_sz2, uint8_t lookahead_sz2); + +/* Free a decoder. */ +void heatshrink_decoder_free(heatshrink_decoder *hsd); +#endif + +/* Reset a decoder. */ +void heatshrink_decoder_reset(heatshrink_decoder *hsd); + +/* Sink at most SIZE bytes from IN_BUF into the decoder. *INPUT_SIZE is set to + * indicate how many bytes were actually sunk (in case a buffer was filled). */ +HSD_sink_res heatshrink_decoder_sink(heatshrink_decoder *hsd, + uint8_t *in_buf, size_t size, size_t *input_size); + +/* Poll for output from the decoder, copying at most OUT_BUF_SIZE bytes into + * OUT_BUF (setting *OUTPUT_SIZE to the actual amount copied). */ +HSD_poll_res heatshrink_decoder_poll(heatshrink_decoder *hsd, + uint8_t *out_buf, size_t out_buf_size, size_t *output_size); + +/* Notify the dencoder that the input stream is finished. + * If the return value is HSDR_FINISH_MORE, there is still more output, so + * call heatshrink_decoder_poll and repeat. */ +HSD_finish_res heatshrink_decoder_finish(heatshrink_decoder *hsd); + +#endif diff --git a/Starduino_8bit_Super_Mario_Tree_Topper/Starduino_8bit_Super_Mario_Tree_Topper.ino b/Starduino_8bit_Super_Mario_Tree_Topper/Starduino_8bit_Super_Mario_Tree_Topper.ino index 9c3eebd7e..948c43281 100644 --- a/Starduino_8bit_Super_Mario_Tree_Topper/Starduino_8bit_Super_Mario_Tree_Topper.ino +++ b/Starduino_8bit_Super_Mario_Tree_Topper/Starduino_8bit_Super_Mario_Tree_Topper.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2018 Mikey Sklar for Adafruit Industries +// +// SPDX-License-Identifier: MIT + #include #define LED_PIN 0 diff --git a/Starduino_8bit_Super_Mario_Tree_Topper/code.py b/Starduino_8bit_Super_Mario_Tree_Topper/code.py index 327b17f6c..4e80f5531 100644 --- a/Starduino_8bit_Super_Mario_Tree_Topper/code.py +++ b/Starduino_8bit_Super_Mario_Tree_Topper/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2018 Mikey Sklar for Adafruit Industries +# +# SPDX-License-Identifier: MIT + import board import neopixel import adafruit_fancyled.adafruit_fancyled as fancy diff --git a/Trinkey_QT2040_TRNG_Gadget/python/trng_read_csv.py b/Trinkey_QT2040_TRNG_Gadget/python/trng_read_csv.py index cbd5c5705..75895212c 100755 --- a/Trinkey_QT2040_TRNG_Gadget/python/trng_read_csv.py +++ b/Trinkey_QT2040_TRNG_Gadget/python/trng_read_csv.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2021 Carter Nelson for Adafruit Industries +# +# SPDX-License-Identifier: MIT + import serial # open serial port diff --git a/Trinkey_QT2040_TRNG_Gadget/python/trng_read_json.py b/Trinkey_QT2040_TRNG_Gadget/python/trng_read_json.py index 1c31676b1..2043b236f 100755 --- a/Trinkey_QT2040_TRNG_Gadget/python/trng_read_json.py +++ b/Trinkey_QT2040_TRNG_Gadget/python/trng_read_json.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2021 Carter Nelson for Adafruit Industries +# +# SPDX-License-Identifier: MIT + import json import serial diff --git a/Trinkey_QT2040_TRNG_Gadget/python/trng_read_raw.py b/Trinkey_QT2040_TRNG_Gadget/python/trng_read_raw.py index 4c59b0cf1..510ac809b 100755 --- a/Trinkey_QT2040_TRNG_Gadget/python/trng_read_raw.py +++ b/Trinkey_QT2040_TRNG_Gadget/python/trng_read_raw.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2021 Carter Nelson for Adafruit Industries +# +# SPDX-License-Identifier: MIT + import serial # how many bytes to read? diff --git a/Trinkey_QT2040_TRNG_Gadget/trinkey_rp2040_trust_m_trng/trinkey_rp2040_trust_m_trng.ino b/Trinkey_QT2040_TRNG_Gadget/trinkey_rp2040_trust_m_trng/trinkey_rp2040_trust_m_trng.ino index 6859b8691..6f9250e13 100755 --- a/Trinkey_QT2040_TRNG_Gadget/trinkey_rp2040_trust_m_trng/trinkey_rp2040_trust_m_trng.ino +++ b/Trinkey_QT2040_TRNG_Gadget/trinkey_rp2040_trust_m_trng/trinkey_rp2040_trust_m_trng.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2021 Carter Nelson for Adafruit Industries +// +// SPDX-License-Identifier: MIT + #include #include "OPTIGATrustM.h"