diff --git a/examples/spi_max7219/Makefile b/examples/spi_max7219/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..4017a9d934dfa7593e6cef4f7978e23c2507a522
--- /dev/null
+++ b/examples/spi_max7219/Makefile
@@ -0,0 +1,10 @@
+all : flash
+
+TARGET:=spi_max7219
+
+include ../../ch32v003fun/ch32v003fun.mk
+
+flash : cv_flash
+clean : cv_clean
+
+
diff --git a/examples/spi_max7219/README.md b/examples/spi_max7219/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..2605e21cfb9e5dd76301cfa2a13b61cb164a0094
--- /dev/null
+++ b/examples/spi_max7219/README.md
@@ -0,0 +1,19 @@
+# MAX7219 8 digit 7 segment display demo
+
+This example for the `max7219_spi_driver` and `max7219_spi_driver_extended` library demonstrates controlling a MAX7219 or MAX7221 based display over SPI with basic and advanced text writing, and at least one example of every available display function in some capacity.
+
+---
+
+The MAX7219 and MAX7221 chipsets are used in many 8 character 7 segment and 8x8 single colour dot matrix displays which can be purchased preassembled on eBay and AliExpress very cheaply. The abundance and low cost of these displays makes them a great companion for small projects requiring a display output that is more capable than single LEDs but not as complex as something like an LCD.
+
+---
+
+The example expects you to connect a MAX7219 based 7 segment 8 character display to your CH32V003 like so:
+- `DIN` / `MOSI` to `PC6`
+- `SCLK` to `PC5`
+- `CS` to `PD0`
+
+You can choose which examples will be shown on the display by changing the `spi_max7219.c` file in the marked demo selection section. All examples are enabled by default.
+
+Once running, you'll see one of the many examples being displayed like so:
+![Demo of the MAX7219 based 8 digit 7 segment display connected to a CH32V003 dev board, in operation](demo_pic.jpg)
\ No newline at end of file
diff --git a/examples/spi_max7219/demo_pic.jpg b/examples/spi_max7219/demo_pic.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..33b15eb2cab5b746ab7105910e78c82bf92cab2e
Binary files /dev/null and b/examples/spi_max7219/demo_pic.jpg differ
diff --git a/examples/spi_max7219/funconfig.h b/examples/spi_max7219/funconfig.h
new file mode 100644
index 0000000000000000000000000000000000000000..37a2af8d0bacc627e3dc7745feecaf1bed95d6ae
--- /dev/null
+++ b/examples/spi_max7219/funconfig.h
@@ -0,0 +1,6 @@
+#ifndef _FUNCONFIG_H
+#define _FUNCONFIG_H
+
+#define CH32V003           1
+
+#endif
diff --git a/examples/spi_max7219/max7219_spi_driver.h b/examples/spi_max7219/max7219_spi_driver.h
new file mode 100644
index 0000000000000000000000000000000000000000..0a2ec35729de3d32b16df6302cc7c9bce38a5866
--- /dev/null
+++ b/examples/spi_max7219/max7219_spi_driver.h
@@ -0,0 +1,236 @@
+/* 
+ * SPI based driver for the MAX7219 display driver (https://www.analog.com/media/en/technical-documentation/data-sheets/MAX7219-MAX7221.pdf)
+ * 
+ * The driver can be used for 64 discrete LED control, or for 8 digits of 7 segment (+ decimal) displays. It includes a basic 7 segment display font called Code B
+ * which is made available with this library, as well as various other functions such as multiplexer scan limiting, digital brightness control and font decoding.
+ * 
+ * The one-byte segment arrangement in the digit registers appear like so:
+ * 
+ *     A
+ *    ---
+ * F | G | B
+ *    --- 
+ * E |   | C
+ *    --- 
+ *     D   . DP
+ * 
+ * +-----+----+----+----+----+----+----+----+----+
+ * | Bit | B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 |
+ * +-----+----+----+----+----+----+----+----+----+
+ * | Seg | DP |  A |  B |  C |  D |  E |  F |  G |
+ * +-----+----+----+----+----+----+----+----+----+
+ * 
+ * On standard 8 digit boards, the 0th digit (MAX7219_REGISTER_DIGIT0) is on the right and the 7th digit (MAX7219_REGISTER_DIGIT7) is on the left.
+ */
+
+//Include guard
+#ifndef MAX7219_SPI_DRIVER_H
+#define MAX7219_SPI_DRIVER_H
+
+//Includes
+#include "ch32v003_SPI.h"
+#include <stdbool.h>
+
+//Instance struct
+struct MAX7219_Display
+{
+    uint8_t displays_in_chain;
+
+    GPIO_TypeDef* chip_select_port;
+    uint8_t chip_select_pin;
+
+    uint8_t last_set_decode_mode;
+};
+
+//Chip select methods
+void MAX7219_select(struct MAX7219_Display display)
+{
+    display.chip_select_port->BSHR |= 0b00000001 << display.chip_select_pin << 16; //Reset pin (active low)
+}
+
+void MAX7219_deselect(struct MAX7219_Display display)
+{
+    display.chip_select_port->BSHR |= 0b00000001 << display.chip_select_pin; //Set pin (active low)
+}
+
+//Raw communication
+#define MAX7219_REGISTER_NOOP 0x00
+/*#define MAX7219_REGISTER_DIGIT0 0x01
+#define MAX7219_REGISTER_DIGIT1 0x02
+#define MAX7219_REGISTER_DIGIT2 0x03
+#define MAX7219_REGISTER_DIGIT3 0x04
+#define MAX7219_REGISTER_DIGIT4 0x05
+#define MAX7219_REGISTER_DIGIT5 0x06
+#define MAX7219_REGISTER_DIGIT6 0x07
+#define MAX7219_REGISTER_DIGIT7 0x08*/
+#define MAX7219_REGISTER_DECODE_MODE 0x09
+#define MAX7219_REGISTER_INTENSITY 0x0A
+#define MAX7219_REGISTER_SCANLIMIT 0x0B
+#define MAX7219_REGISTER_SHUTDOWN 0x0C
+#define MAX7219_REGISTER_DISPLAYTEST 0x0F
+
+void MAX7219_write_register(struct MAX7219_Display display, uint8_t reg, uint8_t data)
+{
+    reg &= 0b00001111; //Remove the top 4 bits as they are not used for the register, and only retain the last 4 bits
+
+    uint16_t packet = reg << 8; //Apply the register address to the final packet in the top 8 bits
+
+    packet |= data; //Apply the data to the final packet in the bottom 8 bits
+
+    MAX7219_select(display); //Select the chip select line
+
+    //Write the packet to the display
+    SPI_begin_16();
+
+    SPI_write_16(packet);
+    SPI_wait_transmit_finished();
+    
+    SPI_end();
+
+    MAX7219_deselect(display); //Deselect the chip select line
+}
+
+//Register helpers
+void MAX7219_shutdown(struct MAX7219_Display display, bool set)
+{
+    MAX7219_write_register(display, MAX7219_REGISTER_SHUTDOWN, !set);
+}
+
+void MAX7219_test(struct MAX7219_Display display, bool set)
+{
+    MAX7219_write_register(display, MAX7219_REGISTER_DISPLAYTEST, set);
+}
+
+#define MAX7219_DECODE_MODE_NONE 0x00
+#define MAX7219_DECODE_MODE_0_ONLY 0x01
+#define MAX7219_DECODE_MODE_0_TO_3_ONLY 0x0F
+#define MAX7219_DECODE_MODE_ALL 0xFF
+
+void MAX7219_set_decode_mode(struct MAX7219_Display display, uint8_t mode)
+{
+    MAX7219_write_register(display, MAX7219_REGISTER_DECODE_MODE, mode);
+    display.last_set_decode_mode = mode;
+}
+
+#define MAX7219_SCANLIMIT_0_ONLY 0x00
+#define MAX7219_SCANLIMIT_01 0x01
+#define MAX7219_SCANLIMIT_012 0x02
+#define MAX7219_SCANLIMIT_0123 0x03
+#define MAX7219_SCANLIMIT_01234 0x04
+#define MAX7219_SCANLIMIT_012345 0x05
+#define MAX7219_SCANLIMIT_0123456 0x06
+#define MAX7219_SCANLIMIT_ALL 0x07
+
+void MAX7219_set_scan_limit(struct MAX7219_Display display, uint8_t limit)
+{
+    limit &= 0b00000111; //Only accept the 3 lsbs for this register
+    MAX7219_write_register(display, MAX7219_REGISTER_SCANLIMIT, limit);
+}
+
+#define MAX7219_BRIGHTNESS_MAX 0x0F
+#define MAX7219_MRIGHTNESS_MIN 0x00
+
+void MAX7219_set_brightness(struct MAX7219_Display display, uint8_t brightness)
+{
+    brightness &= 0b00001111; //Only accept the 4 lsbs for this register
+    MAX7219_write_register(display, MAX7219_REGISTER_INTENSITY, brightness);
+}
+
+//Built in CODE B font
+#define MAX7219_CODEB_ADD_DECPOINT 0x80
+#define MAX7219_CODEB_DASH 0x0A
+#define MAX7219_CODEB_BLANK 0x0F
+#define MAX7219_CODEB_0 0x00
+#define MAX7219_CODEB_1 0x01
+#define MAX7219_CODEB_2 0x02
+#define MAX7219_CODEB_3 0x03
+#define MAX7219_CODEB_4 0x04
+#define MAX7219_CODEB_5 0x05
+#define MAX7219_CODEB_6 0x06
+#define MAX7219_CODEB_7 0x07
+#define MAX7219_CODEB_8 0x08
+#define MAX7219_CODEB_9 0x09
+#define MAX7219_CODEB_E 0x0B
+#define MAX7219_CODEB_H 0x0C
+#define MAX7219_CODEB_L 0x0D
+#define MAX7219_CODEB_P 0x0E
+
+//Raw segment
+#define MAX7219_SEGMENT_DP 0b10000000
+#define MAX7219_SEGMENT_A  0b01000000
+#define MAX7219_SEGMENT_B  0b00100000
+#define MAX7219_SEGMENT_C  0b00010000
+#define MAX7219_SEGMENT_D  0b00001000
+#define MAX7219_SEGMENT_E  0b00000100
+#define MAX7219_SEGMENT_F  0b00000010
+#define MAX7219_SEGMENT_G  0b00000001
+
+void MAX7219_set_digit(struct MAX7219_Display display, uint32_t digit, uint8_t value)
+{
+    uint32_t literalDigit = digit % 8;
+    //uint32_t displayIndex = digit / 8;
+
+    MAX7219_write_register(display, literalDigit + 1, value);
+}
+
+void MAX7219_reset(struct MAX7219_Display display)
+{
+    //Set display brightness to maximum
+    MAX7219_set_brightness(display, MAX7219_BRIGHTNESS_MAX);
+
+    //Set the scan limit to all 8 digits enabled
+    MAX7219_set_scan_limit(display, MAX7219_SCANLIMIT_ALL);
+
+    //Enable Code-B decode on all digits
+    MAX7219_set_decode_mode(display, MAX7219_DECODE_MODE_ALL);
+
+    //Clear all digits
+    for (size_t digitPos = 0; digitPos < display.displays_in_chain * 8; digitPos++)
+    {
+        MAX7219_set_digit(display, digitPos, MAX7219_CODEB_BLANK);
+    }
+
+    //Take the display out of shutdown
+    MAX7219_shutdown(display, false);
+
+    //Take the display out of test mode
+    MAX7219_test(display, false);
+}
+
+void MAX7219_init(struct MAX7219_Display display)
+{
+    //Default deselected
+    MAX7219_deselect(display);
+
+    //Ensure port is enabled
+    uint32_t selectedPortAddress = (uint32_t)display.chip_select_port;
+
+    switch (selectedPortAddress)
+    {
+        case GPIOA_BASE:
+            RCC->APB2PCENR |= RCC_APB2Periph_GPIOA;
+            break;
+        
+        case GPIOC_BASE:
+            RCC->APB2PCENR |= RCC_APB2Periph_GPIOC;
+            break;
+
+        case GPIOD_BASE:
+            RCC->APB2PCENR |= RCC_APB2Periph_GPIOD;
+            break;
+        
+        default: break;
+    }
+
+    //Enable push-pull on pin
+    display.chip_select_port->CFGLR &= ~(0xf<<(4*display.chip_select_pin));
+    display.chip_select_port->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*display.chip_select_pin);
+
+    //Initialise SPI
+    SPI_init();
+
+    //Clear display to driver defaults
+    MAX7219_reset(display);
+}
+
+#endif //MAX7219_SPI_DRIVER_H include guard
\ No newline at end of file
diff --git a/examples/spi_max7219/max7219_spi_driver_extended.h b/examples/spi_max7219/max7219_spi_driver_extended.h
new file mode 100644
index 0000000000000000000000000000000000000000..cb791c2236ca6a0e9ea4758f887728fe651d7b59
--- /dev/null
+++ b/examples/spi_max7219/max7219_spi_driver_extended.h
@@ -0,0 +1,60 @@
+//Include guard
+#ifndef MAX7219_SPI_DRIVER_EXTENDED_H
+#define MAX7219_SPI_DRIVER_EXTENDED_H
+
+//Includes
+#include "max7219_spi_driver.h"
+
+//---Extended Font---
+//Letters
+#define MAX7219_EXTFONT_A MAX7219_SEGMENT_A | MAX7219_SEGMENT_B | MAX7219_SEGMENT_C | MAX7219_SEGMENT_E | MAX7219_SEGMENT_F | MAX7219_SEGMENT_G
+#define MAX7219_EXTFONT_B MAX7219_SEGMENT_C | MAX7219_SEGMENT_D | MAX7219_SEGMENT_E | MAX7219_SEGMENT_F | MAX7219_SEGMENT_G
+#define MAX7219_EXTFONT_C MAX7219_SEGMENT_A | MAX7219_SEGMENT_D | MAX7219_SEGMENT_E | MAX7219_SEGMENT_F
+#define MAX7219_EXTFONT_C_LOWER MAX7219_SEGMENT_D | MAX7219_SEGMENT_E | MAX7219_SEGMENT_G
+#define MAX7219_EXTFONT_D MAX7219_SEGMENT_B | MAX7219_SEGMENT_C | MAX7219_SEGMENT_D | MAX7219_SEGMENT_E | MAX7219_SEGMENT_G
+#define MAX7219_EXTFONT_E MAX7219_SEGMENT_A | MAX7219_SEGMENT_D | MAX7219_SEGMENT_E | MAX7219_SEGMENT_F | MAX7219_SEGMENT_G
+#define MAX7219_EXTFONT_F MAX7219_SEGMENT_A | MAX7219_SEGMENT_E | MAX7219_SEGMENT_F | MAX7219_SEGMENT_G
+#define MAX7219_EXTFONT_H MAX7219_SEGMENT_B | MAX7219_SEGMENT_C | MAX7219_SEGMENT_E | MAX7219_SEGMENT_F | MAX7219_SEGMENT_G
+#define MAX7219_EXTFONT_H_LOWER MAX7219_SEGMENT_C | MAX7219_SEGMENT_E | MAX7219_SEGMENT_F | MAX7219_SEGMENT_G
+#define MAX7219_EXTFONT_I MAX7219_SEGMENT_E | MAX7219_SEGMENT_F
+#define MAX7219_EXTFONT_I_LOWER MAX7219_SEGMENT_E
+#define MAX7219_EXTFONT_L MAX7219_SEGMENT_D | MAX7219_SEGMENT_E | MAX7219_SEGMENT_F
+#define MAX7219_EXTFONT_L_LOWER MAX7219_SEGMENT_E | MAX7219_SEGMENT_F
+#define MAX7219_EXTFONT_N MAX7219_SEGMENT_C | MAX7219_SEGMENT_E | MAX7219_SEGMENT_G
+#define MAX7219_EXTFONT_O MAX7219_SEGMENT_A | MAX7219_SEGMENT_B | MAX7219_SEGMENT_C | MAX7219_SEGMENT_D | MAX7219_SEGMENT_E | MAX7219_SEGMENT_F
+#define MAX7219_EXTFONT_O_LOWER MAX7219_SEGMENT_C | MAX7219_SEGMENT_D | MAX7219_SEGMENT_E | MAX7219_SEGMENT_G
+#define MAX7219_EXTFONT_P MAX7219_SEGMENT_A | MAX7219_SEGMENT_B | MAX7219_SEGMENT_E | MAX7219_SEGMENT_F | MAX7219_SEGMENT_G
+#define MAX7219_EXTFONT_S MAX7219_SEGMENT_A | MAX7219_SEGMENT_C | MAX7219_SEGMENT_D | MAX7219_SEGMENT_F | MAX7219_SEGMENT_G
+#define MAX7219_EXTFONT_T MAX7219_SEGMENT_D | MAX7219_SEGMENT_E | MAX7219_SEGMENT_F | MAX7219_SEGMENT_G
+#define MAX7219_EXTFONT_U MAX7219_SEGMENT_B | MAX7219_SEGMENT_C | MAX7219_SEGMENT_D | MAX7219_SEGMENT_E | MAX7219_SEGMENT_F
+#define MAX7219_EXTFONT_U_LOWER MAX7219_SEGMENT_C | MAX7219_SEGMENT_D | MAX7219_SEGMENT_E
+#define MAX7219_EXTFONT_X MAX7219_SEGMENT_C | MAX7219_SEGMENT_F
+#define MAX7219_EXTFONT_Y MAX7219_SEGMENT_B | MAX7219_SEGMENT_C | MAX7219_SEGMENT_D | MAX7219_SEGMENT_F | MAX7219_SEGMENT_G
+#define MAX7219_EXTFONT_Z MAX7219_SEGMENT_A | MAX7219_SEGMENT_B | MAX7219_SEGMENT_D | MAX7219_SEGMENT_E | MAX7219_SEGMENT_G
+
+//Numbers
+#define MAX7219_EXTFONT_0 MAX7219_SEGMENT_A | MAX7219_SEGMENT_B | MAX7219_SEGMENT_C | MAX7219_SEGMENT_D | MAX7219_SEGMENT_E | MAX7219_SEGMENT_F
+#define MAX7219_EXTFONT_1 MAX7219_SEGMENT_B | MAX7219_SEGMENT_C
+#define MAX7219_EXTFONT_2 MAX7219_SEGMENT_A | MAX7219_SEGMENT_B | MAX7219_SEGMENT_D | MAX7219_SEGMENT_E | MAX7219_SEGMENT_G
+#define MAX7219_EXTFONT_3 MAX7219_SEGMENT_A | MAX7219_SEGMENT_B | MAX7219_SEGMENT_C | MAX7219_SEGMENT_D | MAX7219_SEGMENT_G
+#define MAX7219_EXTFONT_4 MAX7219_SEGMENT_B | MAX7219_SEGMENT_C | MAX7219_SEGMENT_F | MAX7219_SEGMENT_G
+#define MAX7219_EXTFONT_5 MAX7219_SEGMENT_A | MAX7219_SEGMENT_C | MAX7219_SEGMENT_D | MAX7219_SEGMENT_F | MAX7219_SEGMENT_G
+#define MAX7219_EXTFONT_6 MAX7219_SEGMENT_A | MAX7219_SEGMENT_C | MAX7219_SEGMENT_D | MAX7219_SEGMENT_E | MAX7219_SEGMENT_F | MAX7219_SEGMENT_G
+#define MAX7219_EXTFONT_7 MAX7219_SEGMENT_A | MAX7219_SEGMENT_B | MAX7219_SEGMENT_C
+#define MAX7219_EXTFONT_8 MAX7219_SEGMENT_A | MAX7219_SEGMENT_B | MAX7219_SEGMENT_C | MAX7219_SEGMENT_D | MAX7219_SEGMENT_E | MAX7219_SEGMENT_F | MAX7219_SEGMENT_G
+#define MAX7219_EXTFONT_9 MAX7219_SEGMENT_A | MAX7219_SEGMENT_B | MAX7219_SEGMENT_C | MAX7219_SEGMENT_D | MAX7219_SEGMENT_F | MAX7219_SEGMENT_G
+
+//Symbols
+#define MAX7219_EXTFONT_BLANK 0x00
+#define MAX7219_EXTFONT_DEGREES MAX7219_SEGMENT_A | MAX7219_SEGMENT_B | MAX7219_SEGMENT_F | MAX7219_SEGMENT_G
+#define MAX7219_EXTFONT_EQUALS_TOP MAX7219_SEGMENT_A | MAX7219_SEGMENT_G
+#define MAX7219_EXTFONT_EQUALS_BOTTOM MAX7219_SEGMENT_D | MAX7219_SEGMENT_G
+#define MAX7219_EXTFONT_TRIEQUALS MAX7219_SEGMENT_A | MAX7219_SEGMENT_D | MAX7219_SEGMENT_G
+#define MAX7219_EXTFONT_HYPHEN MAX7219_SEGMENT_G
+#define MAX7219_EXTFONT_UNDERSCORE MAX7219_SEGMENT_D
+#define MAX7219_EXTFONT_OVERSCORE MAX7219_SEGMENT_A
+#define MAX7219_EXTFONT_FORWARDSLASH MAX7219_SEGMENT_B | MAX7219_SEGMENT_E | MAX7219_SEGMENT_G
+#define MAX7219_EXTFONT_BACKSLASH MAX7219_SEGMENT_C | MAX7219_SEGMENT_F | MAX7219_SEGMENT_G
+#define MAX7219_EXTFONT_DECIMAL MAX7219_SEGMENT_DP
+
+#endif //MAX7219_SPI_DRIVER_EXTENDED_H include guard
\ No newline at end of file
diff --git a/examples/spi_max7219/spi_max7219.c b/examples/spi_max7219/spi_max7219.c
new file mode 100644
index 0000000000000000000000000000000000000000..a430a2c5b89337dc7c463cf6ac7e364473aa14a0
--- /dev/null
+++ b/examples/spi_max7219/spi_max7219.c
@@ -0,0 +1,691 @@
+#define CH32V003_SPI_SPEED_HZ 1000000
+
+#define CH32V003_SPI_IMPLEMENTATION
+#define CH32V003_SPI_DIRECTION_1LINE_TX
+#define CH32V003_SPI_CLK_MODE_POL0_PHA0
+#define CH32V003_SPI_NSS_SOFTWARE_ANY_MANUAL
+
+//Control which demos you want to see here
+#define DEMO_DISPLAY_TEST
+#define DEMO_CODEB
+#define DEMO_EXTENDED_FONT
+#define DEMO_HELLO_BLINK
+#define DEMO_FIGURES_OF_EIGHT
+#define DEMO_TOGETHER_TWIRLS
+#define DEMO_COUNTER_TWIRLS
+#define DEMO_KNIGHTRIDER_DECIMAL
+#define DEMO_KNIGHTRIDER_DASH
+#define DEMO_INTENSITY_FADE_DECIMALS
+#define DEMO_INTENSITY_FADE_DIGITS
+#define DEMO_LED_CHASE
+
+#include "ch32v003fun.h"
+#include <stdio.h>
+#include "max7219_spi_driver.h"
+#include "max7219_spi_driver_extended.h"
+
+//MOSI on PC6, SCLK on PC5, software controlled CS on PD0
+
+int main()
+{
+    SystemInit();
+
+    struct MAX7219_Display display =
+    {
+        .displays_in_chain = 1,
+
+        .chip_select_port = GPIOD,
+        .chip_select_pin = 0
+    };
+
+    MAX7219_init(display);
+
+    while(1)
+    {
+        #ifdef DEMO_DISPLAY_TEST
+        //Display test on
+        MAX7219_test(display, true);
+        Delay_Ms(1000);
+
+        //Display test off
+        MAX7219_test(display, false);
+        #endif
+
+        #ifdef DEMO_CODEB
+        //Code B non-decimal
+        MAX7219_set_decode_mode(display, MAX7219_DECODE_MODE_ALL);
+
+        MAX7219_set_digit(display, 7, MAX7219_CODEB_0);
+        MAX7219_set_digit(display, 6, MAX7219_CODEB_1);
+        MAX7219_set_digit(display, 5, MAX7219_CODEB_2);
+        MAX7219_set_digit(display, 4, MAX7219_CODEB_3);
+        MAX7219_set_digit(display, 3, MAX7219_CODEB_4);
+        MAX7219_set_digit(display, 2, MAX7219_CODEB_5);
+        MAX7219_set_digit(display, 1, MAX7219_CODEB_6);
+        MAX7219_set_digit(display, 0, MAX7219_CODEB_7);
+
+        Delay_Ms(3000);
+
+        MAX7219_set_digit(display, 7, MAX7219_CODEB_8);
+        MAX7219_set_digit(display, 6, MAX7219_CODEB_9);
+        MAX7219_set_digit(display, 5, MAX7219_CODEB_DASH);
+        MAX7219_set_digit(display, 4, MAX7219_CODEB_H);
+        MAX7219_set_digit(display, 3, MAX7219_CODEB_E);
+        MAX7219_set_digit(display, 2, MAX7219_CODEB_L);
+        MAX7219_set_digit(display, 1, MAX7219_CODEB_P);
+        MAX7219_set_digit(display, 0, MAX7219_CODEB_BLANK);
+
+        Delay_Ms(3000);
+
+        //Code B decimal
+        MAX7219_set_digit(display, 7, MAX7219_CODEB_0 | MAX7219_CODEB_ADD_DECPOINT);
+        MAX7219_set_digit(display, 6, MAX7219_CODEB_1 | MAX7219_CODEB_ADD_DECPOINT);
+        MAX7219_set_digit(display, 5, MAX7219_CODEB_2 | MAX7219_CODEB_ADD_DECPOINT);
+        MAX7219_set_digit(display, 4, MAX7219_CODEB_3 | MAX7219_CODEB_ADD_DECPOINT);
+        MAX7219_set_digit(display, 3, MAX7219_CODEB_4 | MAX7219_CODEB_ADD_DECPOINT);
+        MAX7219_set_digit(display, 2, MAX7219_CODEB_5 | MAX7219_CODEB_ADD_DECPOINT);
+        MAX7219_set_digit(display, 1, MAX7219_CODEB_6 | MAX7219_CODEB_ADD_DECPOINT);
+        MAX7219_set_digit(display, 0, MAX7219_CODEB_7 | MAX7219_CODEB_ADD_DECPOINT);
+
+        Delay_Ms(3000);
+
+        MAX7219_set_digit(display, 7, MAX7219_CODEB_8 | MAX7219_CODEB_ADD_DECPOINT);
+        MAX7219_set_digit(display, 6, MAX7219_CODEB_9 | MAX7219_CODEB_ADD_DECPOINT);
+        MAX7219_set_digit(display, 5, MAX7219_CODEB_DASH | MAX7219_CODEB_ADD_DECPOINT);
+        MAX7219_set_digit(display, 4, MAX7219_CODEB_H | MAX7219_CODEB_ADD_DECPOINT);
+        MAX7219_set_digit(display, 3, MAX7219_CODEB_E | MAX7219_CODEB_ADD_DECPOINT);
+        MAX7219_set_digit(display, 2, MAX7219_CODEB_L | MAX7219_CODEB_ADD_DECPOINT);
+        MAX7219_set_digit(display, 1, MAX7219_CODEB_P | MAX7219_CODEB_ADD_DECPOINT);
+        MAX7219_set_digit(display, 0, MAX7219_CODEB_BLANK | MAX7219_CODEB_ADD_DECPOINT);
+
+        Delay_Ms(3000);
+        #endif
+
+        #ifdef DEMO_EXTENDED_FONT
+        //Extended font
+        MAX7219_set_decode_mode(display, MAX7219_DECODE_MODE_NONE);
+
+        MAX7219_set_digit(display, 7, MAX7219_EXTFONT_A);
+        MAX7219_set_digit(display, 6, MAX7219_EXTFONT_B);
+        MAX7219_set_digit(display, 5, MAX7219_EXTFONT_C);
+        MAX7219_set_digit(display, 4, MAX7219_EXTFONT_C_LOWER);
+        MAX7219_set_digit(display, 3, MAX7219_EXTFONT_D);
+        MAX7219_set_digit(display, 2, MAX7219_EXTFONT_E);
+        MAX7219_set_digit(display, 1, MAX7219_EXTFONT_F);
+        MAX7219_set_digit(display, 0, MAX7219_EXTFONT_H);
+
+        Delay_Ms(3000);
+
+        MAX7219_set_digit(display, 7, MAX7219_EXTFONT_H_LOWER);
+        MAX7219_set_digit(display, 6, MAX7219_EXTFONT_I);
+        MAX7219_set_digit(display, 5, MAX7219_EXTFONT_I_LOWER);
+        MAX7219_set_digit(display, 4, MAX7219_EXTFONT_L);
+        MAX7219_set_digit(display, 3, MAX7219_EXTFONT_L_LOWER);
+        MAX7219_set_digit(display, 2, MAX7219_EXTFONT_N);
+        MAX7219_set_digit(display, 1, MAX7219_EXTFONT_O);
+        MAX7219_set_digit(display, 0, MAX7219_EXTFONT_O_LOWER);
+
+        Delay_Ms(3000);
+
+        MAX7219_set_digit(display, 7, MAX7219_EXTFONT_P);
+        MAX7219_set_digit(display, 6, MAX7219_EXTFONT_S);
+        MAX7219_set_digit(display, 5, MAX7219_EXTFONT_T);
+        MAX7219_set_digit(display, 4, MAX7219_EXTFONT_U);
+        MAX7219_set_digit(display, 3, MAX7219_EXTFONT_U_LOWER);
+        MAX7219_set_digit(display, 2, MAX7219_EXTFONT_X);
+        MAX7219_set_digit(display, 1, MAX7219_EXTFONT_Y);
+        MAX7219_set_digit(display, 0, MAX7219_EXTFONT_Z);
+
+        Delay_Ms(3000);
+
+        MAX7219_set_digit(display, 7, MAX7219_EXTFONT_0);
+        MAX7219_set_digit(display, 6, MAX7219_EXTFONT_1);
+        MAX7219_set_digit(display, 5, MAX7219_EXTFONT_2);
+        MAX7219_set_digit(display, 4, MAX7219_EXTFONT_3);
+        MAX7219_set_digit(display, 3, MAX7219_EXTFONT_4);
+        MAX7219_set_digit(display, 2, MAX7219_EXTFONT_5);
+        MAX7219_set_digit(display, 1, MAX7219_EXTFONT_6);
+        MAX7219_set_digit(display, 0, MAX7219_EXTFONT_7);
+
+        Delay_Ms(3000);
+
+        MAX7219_set_digit(display, 7, MAX7219_EXTFONT_8);
+        MAX7219_set_digit(display, 6, MAX7219_EXTFONT_9);
+        MAX7219_set_digit(display, 5, MAX7219_EXTFONT_BLANK);
+        MAX7219_set_digit(display, 4, MAX7219_EXTFONT_BLANK);
+        MAX7219_set_digit(display, 3, MAX7219_EXTFONT_BLANK);
+        MAX7219_set_digit(display, 2, MAX7219_EXTFONT_BLANK);
+        MAX7219_set_digit(display, 1, MAX7219_EXTFONT_BLANK);
+        MAX7219_set_digit(display, 0, MAX7219_EXTFONT_BLANK);
+
+        Delay_Ms(3000);
+
+        MAX7219_set_digit(display, 7, MAX7219_EXTFONT_DEGREES);
+        MAX7219_set_digit(display, 6, MAX7219_EXTFONT_EQUALS_TOP);
+        MAX7219_set_digit(display, 5, MAX7219_EXTFONT_EQUALS_BOTTOM);
+        MAX7219_set_digit(display, 4, MAX7219_EXTFONT_TRIEQUALS);
+        MAX7219_set_digit(display, 3, MAX7219_EXTFONT_HYPHEN);
+        MAX7219_set_digit(display, 2, MAX7219_EXTFONT_UNDERSCORE);
+        MAX7219_set_digit(display, 1, MAX7219_EXTFONT_OVERSCORE);
+        MAX7219_set_digit(display, 0, MAX7219_EXTFONT_FORWARDSLASH);
+
+        Delay_Ms(3000);
+
+        MAX7219_set_digit(display, 7, MAX7219_EXTFONT_BACKSLASH);
+        MAX7219_set_digit(display, 6, MAX7219_EXTFONT_DECIMAL);
+        MAX7219_set_digit(display, 5, MAX7219_EXTFONT_BLANK);
+        MAX7219_set_digit(display, 4, MAX7219_EXTFONT_BLANK);
+        MAX7219_set_digit(display, 3, MAX7219_EXTFONT_BLANK);
+        MAX7219_set_digit(display, 2, MAX7219_EXTFONT_BLANK);
+        MAX7219_set_digit(display, 1, MAX7219_EXTFONT_BLANK);
+        MAX7219_set_digit(display, 0, MAX7219_EXTFONT_BLANK);
+
+        Delay_Ms(3000);
+        #endif
+
+        #ifdef DEMO_HELLO_BLINK
+        MAX7219_set_decode_mode(display, MAX7219_DECODE_MODE_NONE);
+
+        MAX7219_set_digit(display, 7, MAX7219_EXTFONT_H);
+        MAX7219_set_digit(display, 6, MAX7219_EXTFONT_E);
+        MAX7219_set_digit(display, 5, MAX7219_EXTFONT_L);
+        MAX7219_set_digit(display, 4, MAX7219_EXTFONT_L);
+        MAX7219_set_digit(display, 3, MAX7219_EXTFONT_O);
+        MAX7219_set_digit(display, 2, MAX7219_EXTFONT_BLANK);
+        MAX7219_set_digit(display, 1, MAX7219_EXTFONT_BLANK);
+        MAX7219_set_digit(display, 0, MAX7219_EXTFONT_BLANK);
+
+        Delay_Ms(500);
+
+        MAX7219_shutdown(display, true);
+
+        Delay_Ms(500);
+
+        MAX7219_shutdown(display, false);
+
+        Delay_Ms(500);
+
+        MAX7219_shutdown(display, true);
+
+        Delay_Ms(500);
+
+        MAX7219_shutdown(display, false);
+
+        Delay_Ms(500);
+
+        MAX7219_shutdown(display, true);
+
+        Delay_Ms(500);
+
+        MAX7219_shutdown(display, false);
+        #endif
+
+        #ifdef DEMO_FIGURES_OF_EIGHT
+        //Figures of 8 (HP style)
+        MAX7219_set_decode_mode(display, MAX7219_DECODE_MODE_NONE);
+        
+        MAX7219_set_digit(display, 7, MAX7219_EXTFONT_BLANK);
+        MAX7219_set_digit(display, 6, MAX7219_EXTFONT_BLANK);
+        MAX7219_set_digit(display, 5, MAX7219_EXTFONT_BLANK);
+        MAX7219_set_digit(display, 4, MAX7219_EXTFONT_BLANK);
+        MAX7219_set_digit(display, 3, MAX7219_EXTFONT_BLANK);
+        MAX7219_set_digit(display, 2, MAX7219_EXTFONT_BLANK);
+        MAX7219_set_digit(display, 1, MAX7219_EXTFONT_BLANK);
+        MAX7219_set_digit(display, 0, MAX7219_EXTFONT_BLANK);
+
+        for (size_t figureeightcycles = 0; figureeightcycles < 8; figureeightcycles++)
+        {
+            MAX7219_set_digit(display, 7, MAX7219_SEGMENT_G);
+            MAX7219_set_digit(display, 6, MAX7219_SEGMENT_G);
+            MAX7219_set_digit(display, 5, MAX7219_SEGMENT_G);
+            MAX7219_set_digit(display, 4, MAX7219_SEGMENT_G);
+            MAX7219_set_digit(display, 3, MAX7219_SEGMENT_G);
+            MAX7219_set_digit(display, 2, MAX7219_SEGMENT_G);
+            MAX7219_set_digit(display, 1, MAX7219_SEGMENT_G);
+            MAX7219_set_digit(display, 0, MAX7219_SEGMENT_G);
+            Delay_Ms(75);
+
+            MAX7219_set_digit(display, 7, MAX7219_SEGMENT_B);
+            MAX7219_set_digit(display, 6, MAX7219_SEGMENT_B);
+            MAX7219_set_digit(display, 5, MAX7219_SEGMENT_B);
+            MAX7219_set_digit(display, 4, MAX7219_SEGMENT_B);
+            MAX7219_set_digit(display, 3, MAX7219_SEGMENT_B);
+            MAX7219_set_digit(display, 2, MAX7219_SEGMENT_B);
+            MAX7219_set_digit(display, 1, MAX7219_SEGMENT_B);
+            MAX7219_set_digit(display, 0, MAX7219_SEGMENT_B);
+            Delay_Ms(75);
+
+            MAX7219_set_digit(display, 7, MAX7219_SEGMENT_A);
+            MAX7219_set_digit(display, 6, MAX7219_SEGMENT_A);
+            MAX7219_set_digit(display, 5, MAX7219_SEGMENT_A);
+            MAX7219_set_digit(display, 4, MAX7219_SEGMENT_A);
+            MAX7219_set_digit(display, 3, MAX7219_SEGMENT_A);
+            MAX7219_set_digit(display, 2, MAX7219_SEGMENT_A);
+            MAX7219_set_digit(display, 1, MAX7219_SEGMENT_A);
+            MAX7219_set_digit(display, 0, MAX7219_SEGMENT_A);
+            Delay_Ms(75);
+
+            MAX7219_set_digit(display, 7, MAX7219_SEGMENT_F);
+            MAX7219_set_digit(display, 6, MAX7219_SEGMENT_F);
+            MAX7219_set_digit(display, 5, MAX7219_SEGMENT_F);
+            MAX7219_set_digit(display, 4, MAX7219_SEGMENT_F);
+            MAX7219_set_digit(display, 3, MAX7219_SEGMENT_F);
+            MAX7219_set_digit(display, 2, MAX7219_SEGMENT_F);
+            MAX7219_set_digit(display, 1, MAX7219_SEGMENT_F);
+            MAX7219_set_digit(display, 0, MAX7219_SEGMENT_F);
+            Delay_Ms(75);
+
+            MAX7219_set_digit(display, 7, MAX7219_SEGMENT_G);
+            MAX7219_set_digit(display, 6, MAX7219_SEGMENT_G);
+            MAX7219_set_digit(display, 5, MAX7219_SEGMENT_G);
+            MAX7219_set_digit(display, 4, MAX7219_SEGMENT_G);
+            MAX7219_set_digit(display, 3, MAX7219_SEGMENT_G);
+            MAX7219_set_digit(display, 2, MAX7219_SEGMENT_G);
+            MAX7219_set_digit(display, 1, MAX7219_SEGMENT_G);
+            MAX7219_set_digit(display, 0, MAX7219_SEGMENT_G);
+            Delay_Ms(75);
+
+            MAX7219_set_digit(display, 7, MAX7219_SEGMENT_C);
+            MAX7219_set_digit(display, 6, MAX7219_SEGMENT_C);
+            MAX7219_set_digit(display, 5, MAX7219_SEGMENT_C);
+            MAX7219_set_digit(display, 4, MAX7219_SEGMENT_C);
+            MAX7219_set_digit(display, 3, MAX7219_SEGMENT_C);
+            MAX7219_set_digit(display, 2, MAX7219_SEGMENT_C);
+            MAX7219_set_digit(display, 1, MAX7219_SEGMENT_C);
+            MAX7219_set_digit(display, 0, MAX7219_SEGMENT_C);
+            Delay_Ms(75);
+
+            MAX7219_set_digit(display, 7, MAX7219_SEGMENT_D);
+            MAX7219_set_digit(display, 6, MAX7219_SEGMENT_D);
+            MAX7219_set_digit(display, 5, MAX7219_SEGMENT_D);
+            MAX7219_set_digit(display, 4, MAX7219_SEGMENT_D);
+            MAX7219_set_digit(display, 3, MAX7219_SEGMENT_D);
+            MAX7219_set_digit(display, 2, MAX7219_SEGMENT_D);
+            MAX7219_set_digit(display, 1, MAX7219_SEGMENT_D);
+            MAX7219_set_digit(display, 0, MAX7219_SEGMENT_D);
+            Delay_Ms(75);
+
+            MAX7219_set_digit(display, 7, MAX7219_SEGMENT_E);
+            MAX7219_set_digit(display, 6, MAX7219_SEGMENT_E);
+            MAX7219_set_digit(display, 5, MAX7219_SEGMENT_E);
+            MAX7219_set_digit(display, 4, MAX7219_SEGMENT_E);
+            MAX7219_set_digit(display, 3, MAX7219_SEGMENT_E);
+            MAX7219_set_digit(display, 2, MAX7219_SEGMENT_E);
+            MAX7219_set_digit(display, 1, MAX7219_SEGMENT_E);
+            MAX7219_set_digit(display, 0, MAX7219_SEGMENT_E);
+            Delay_Ms(75);
+        }
+        #endif
+
+        #ifdef DEMO_TOGETHER_TWIRLS
+        //Together twirls
+        MAX7219_set_decode_mode(display, MAX7219_DECODE_MODE_NONE);
+
+        for (size_t togethertwirlcycles = 0; togethertwirlcycles < 8; togethertwirlcycles++)
+        {
+            MAX7219_set_digit(display, 7, MAX7219_SEGMENT_A | MAX7219_SEGMENT_G);
+            MAX7219_set_digit(display, 6, MAX7219_SEGMENT_A | MAX7219_SEGMENT_G);
+            MAX7219_set_digit(display, 5, MAX7219_SEGMENT_A | MAX7219_SEGMENT_G);
+            MAX7219_set_digit(display, 4, MAX7219_SEGMENT_A | MAX7219_SEGMENT_G);
+            MAX7219_set_digit(display, 3, MAX7219_SEGMENT_A | MAX7219_SEGMENT_G);
+            MAX7219_set_digit(display, 2, MAX7219_SEGMENT_A | MAX7219_SEGMENT_G);
+            MAX7219_set_digit(display, 1, MAX7219_SEGMENT_A | MAX7219_SEGMENT_G);
+            MAX7219_set_digit(display, 0, MAX7219_SEGMENT_A | MAX7219_SEGMENT_G);
+            Delay_Ms(250);
+
+            MAX7219_set_digit(display, 7, MAX7219_SEGMENT_B | MAX7219_SEGMENT_C);
+            MAX7219_set_digit(display, 6, MAX7219_SEGMENT_B | MAX7219_SEGMENT_C);
+            MAX7219_set_digit(display, 5, MAX7219_SEGMENT_B | MAX7219_SEGMENT_C);
+            MAX7219_set_digit(display, 4, MAX7219_SEGMENT_B | MAX7219_SEGMENT_C);
+            MAX7219_set_digit(display, 3, MAX7219_SEGMENT_B | MAX7219_SEGMENT_C);
+            MAX7219_set_digit(display, 2, MAX7219_SEGMENT_B | MAX7219_SEGMENT_C);
+            MAX7219_set_digit(display, 1, MAX7219_SEGMENT_B | MAX7219_SEGMENT_C);
+            MAX7219_set_digit(display, 0, MAX7219_SEGMENT_B | MAX7219_SEGMENT_C);
+            Delay_Ms(250);
+
+            MAX7219_set_digit(display, 7, MAX7219_SEGMENT_G | MAX7219_SEGMENT_D);
+            MAX7219_set_digit(display, 6, MAX7219_SEGMENT_G | MAX7219_SEGMENT_D);
+            MAX7219_set_digit(display, 5, MAX7219_SEGMENT_G | MAX7219_SEGMENT_D);
+            MAX7219_set_digit(display, 4, MAX7219_SEGMENT_G | MAX7219_SEGMENT_D);
+            MAX7219_set_digit(display, 3, MAX7219_SEGMENT_G | MAX7219_SEGMENT_D);
+            MAX7219_set_digit(display, 2, MAX7219_SEGMENT_G | MAX7219_SEGMENT_D);
+            MAX7219_set_digit(display, 1, MAX7219_SEGMENT_G | MAX7219_SEGMENT_D);
+            MAX7219_set_digit(display, 0, MAX7219_SEGMENT_G | MAX7219_SEGMENT_D);
+            Delay_Ms(250);
+
+            MAX7219_set_digit(display, 7, MAX7219_SEGMENT_E | MAX7219_SEGMENT_F);
+            MAX7219_set_digit(display, 6, MAX7219_SEGMENT_E | MAX7219_SEGMENT_F);
+            MAX7219_set_digit(display, 5, MAX7219_SEGMENT_E | MAX7219_SEGMENT_F);
+            MAX7219_set_digit(display, 4, MAX7219_SEGMENT_E | MAX7219_SEGMENT_F);
+            MAX7219_set_digit(display, 3, MAX7219_SEGMENT_E | MAX7219_SEGMENT_F);
+            MAX7219_set_digit(display, 2, MAX7219_SEGMENT_E | MAX7219_SEGMENT_F);
+            MAX7219_set_digit(display, 1, MAX7219_SEGMENT_E | MAX7219_SEGMENT_F);
+            MAX7219_set_digit(display, 0, MAX7219_SEGMENT_E | MAX7219_SEGMENT_F);
+            Delay_Ms(250);
+        }
+        #endif
+
+        #ifdef DEMO_COUNTER_TWIRLS
+        //Counter twirls
+        MAX7219_set_decode_mode(display, MAX7219_DECODE_MODE_NONE);
+
+        for (size_t countertwirlcycles = 0; countertwirlcycles < 8; countertwirlcycles++)
+        {
+            MAX7219_set_digit(display, 7, MAX7219_SEGMENT_F | MAX7219_SEGMENT_C);
+            MAX7219_set_digit(display, 6, MAX7219_SEGMENT_F | MAX7219_SEGMENT_C);
+            MAX7219_set_digit(display, 5, MAX7219_SEGMENT_F | MAX7219_SEGMENT_C);
+            MAX7219_set_digit(display, 4, MAX7219_SEGMENT_F | MAX7219_SEGMENT_C);
+            MAX7219_set_digit(display, 3, MAX7219_SEGMENT_F | MAX7219_SEGMENT_C);
+            MAX7219_set_digit(display, 2, MAX7219_SEGMENT_F | MAX7219_SEGMENT_C);
+            MAX7219_set_digit(display, 1, MAX7219_SEGMENT_F | MAX7219_SEGMENT_C);
+            MAX7219_set_digit(display, 0, MAX7219_SEGMENT_F | MAX7219_SEGMENT_C);
+            Delay_Ms(250);
+
+            MAX7219_set_digit(display, 7, MAX7219_SEGMENT_A | MAX7219_SEGMENT_G);
+            MAX7219_set_digit(display, 6, MAX7219_SEGMENT_A | MAX7219_SEGMENT_G);
+            MAX7219_set_digit(display, 5, MAX7219_SEGMENT_A | MAX7219_SEGMENT_G);
+            MAX7219_set_digit(display, 4, MAX7219_SEGMENT_A | MAX7219_SEGMENT_G);
+            MAX7219_set_digit(display, 3, MAX7219_SEGMENT_A | MAX7219_SEGMENT_G);
+            MAX7219_set_digit(display, 2, MAX7219_SEGMENT_A | MAX7219_SEGMENT_G);
+            MAX7219_set_digit(display, 1, MAX7219_SEGMENT_A | MAX7219_SEGMENT_G);
+            MAX7219_set_digit(display, 0, MAX7219_SEGMENT_A | MAX7219_SEGMENT_G);
+            Delay_Ms(250);
+
+            MAX7219_set_digit(display, 7, MAX7219_SEGMENT_B | MAX7219_SEGMENT_E);
+            MAX7219_set_digit(display, 6, MAX7219_SEGMENT_B | MAX7219_SEGMENT_E);
+            MAX7219_set_digit(display, 5, MAX7219_SEGMENT_B | MAX7219_SEGMENT_E);
+            MAX7219_set_digit(display, 4, MAX7219_SEGMENT_B | MAX7219_SEGMENT_E);
+            MAX7219_set_digit(display, 3, MAX7219_SEGMENT_B | MAX7219_SEGMENT_E);
+            MAX7219_set_digit(display, 2, MAX7219_SEGMENT_B | MAX7219_SEGMENT_E);
+            MAX7219_set_digit(display, 1, MAX7219_SEGMENT_B | MAX7219_SEGMENT_E);
+            MAX7219_set_digit(display, 0, MAX7219_SEGMENT_B | MAX7219_SEGMENT_E);
+            Delay_Ms(250);
+
+            MAX7219_set_digit(display, 7, MAX7219_SEGMENT_G | MAX7219_SEGMENT_D);
+            MAX7219_set_digit(display, 6, MAX7219_SEGMENT_G | MAX7219_SEGMENT_D);
+            MAX7219_set_digit(display, 5, MAX7219_SEGMENT_G | MAX7219_SEGMENT_D);
+            MAX7219_set_digit(display, 4, MAX7219_SEGMENT_G | MAX7219_SEGMENT_D);
+            MAX7219_set_digit(display, 3, MAX7219_SEGMENT_G | MAX7219_SEGMENT_D);
+            MAX7219_set_digit(display, 2, MAX7219_SEGMENT_G | MAX7219_SEGMENT_D);
+            MAX7219_set_digit(display, 1, MAX7219_SEGMENT_G | MAX7219_SEGMENT_D);
+            MAX7219_set_digit(display, 0, MAX7219_SEGMENT_G | MAX7219_SEGMENT_D);
+            Delay_Ms(250);
+        }
+        #endif
+
+        #ifdef DEMO_KNIGHTRIDER_DECIMAL
+        //Decimal knight-rider-like bounce effect using Code B on decimals
+        MAX7219_set_decode_mode(display, MAX7219_DECODE_MODE_ALL);
+
+        MAX7219_set_digit(display, 7, MAX7219_CODEB_BLANK | MAX7219_CODEB_ADD_DECPOINT);
+        MAX7219_set_digit(display, 6, MAX7219_CODEB_BLANK);
+        MAX7219_set_digit(display, 5, MAX7219_CODEB_BLANK);
+        MAX7219_set_digit(display, 4, MAX7219_CODEB_BLANK);
+        MAX7219_set_digit(display, 3, MAX7219_CODEB_BLANK);
+        MAX7219_set_digit(display, 2, MAX7219_CODEB_BLANK);
+        MAX7219_set_digit(display, 1, MAX7219_CODEB_BLANK);
+        MAX7219_set_digit(display, 0, MAX7219_CODEB_BLANK);
+
+        Delay_Ms(125);
+
+        for (size_t ridercycles = 0; ridercycles < 4; ridercycles++)
+        {
+            size_t position = 7;
+
+            while (position > 0)
+            {
+                //If the next position is within bounds, place a DP there
+                if (position - 1 >= 0) MAX7219_set_digit(display, position - 1, MAX7219_CODEB_BLANK | MAX7219_CODEB_ADD_DECPOINT);
+
+                //Clear current position
+                MAX7219_set_digit(display, position, MAX7219_CODEB_BLANK);
+                
+                //Move onto the next position
+                position--;
+
+                Delay_Ms(125);
+            }
+
+            while (position < 7)
+            {
+                //If the next position is within bounds, place a DP there
+                if (position + 1 <= 7) MAX7219_set_digit(display, position + 1, MAX7219_CODEB_BLANK | MAX7219_CODEB_ADD_DECPOINT);
+
+                //Clear current position
+                MAX7219_set_digit(display, position, MAX7219_CODEB_BLANK);
+                
+                //Move onto the next position
+                position++;
+
+                Delay_Ms(125);
+            }
+        }
+        #endif
+
+        #ifdef DEMO_KNIGHTRIDER_DASH
+        //Decimal knight-rider-like bounce effect using Code B on dashes
+        MAX7219_set_decode_mode(display, MAX7219_DECODE_MODE_ALL);
+
+        MAX7219_set_digit(display, 7, MAX7219_CODEB_DASH);
+        MAX7219_set_digit(display, 6, MAX7219_CODEB_BLANK);
+        MAX7219_set_digit(display, 5, MAX7219_CODEB_BLANK);
+        MAX7219_set_digit(display, 4, MAX7219_CODEB_BLANK);
+        MAX7219_set_digit(display, 3, MAX7219_CODEB_BLANK);
+        MAX7219_set_digit(display, 2, MAX7219_CODEB_BLANK);
+        MAX7219_set_digit(display, 1, MAX7219_CODEB_BLANK);
+        MAX7219_set_digit(display, 0, MAX7219_CODEB_BLANK);
+
+        Delay_Ms(125);
+
+        for (size_t ridercycles = 0; ridercycles < 4; ridercycles++)
+        {
+            size_t position = 7;
+
+            while (position > 0)
+            {
+                //If the next position is within bounds, place a DP there
+                if (position - 1 >= 0) MAX7219_set_digit(display, position - 1, MAX7219_CODEB_DASH);
+
+                //Clear current position
+                MAX7219_set_digit(display, position, MAX7219_CODEB_BLANK);
+                
+                //Move onto the next position
+                position--;
+
+                Delay_Ms(125);
+            }
+
+            while (position < 7)
+            {
+                //If the next position is within bounds, place a DP there
+                if (position + 1 <= 7) MAX7219_set_digit(display, position + 1, MAX7219_CODEB_DASH);
+
+                //Clear current position
+                MAX7219_set_digit(display, position, MAX7219_CODEB_BLANK);
+                
+                //Move onto the next position
+                position++;
+
+                Delay_Ms(125);
+            }
+        }
+        #endif
+
+        #ifdef DEMO_INTENSITY_FADE_DECIMALS
+        //All decimals intensity fade effect
+        MAX7219_set_decode_mode(display, MAX7219_DECODE_MODE_ALL);
+
+        MAX7219_set_digit(display, 7, MAX7219_CODEB_BLANK | MAX7219_CODEB_ADD_DECPOINT);
+        MAX7219_set_digit(display, 6, MAX7219_CODEB_BLANK | MAX7219_CODEB_ADD_DECPOINT);
+        MAX7219_set_digit(display, 5, MAX7219_CODEB_BLANK | MAX7219_CODEB_ADD_DECPOINT);
+        MAX7219_set_digit(display, 4, MAX7219_CODEB_BLANK | MAX7219_CODEB_ADD_DECPOINT);
+        MAX7219_set_digit(display, 3, MAX7219_CODEB_BLANK | MAX7219_CODEB_ADD_DECPOINT);
+        MAX7219_set_digit(display, 2, MAX7219_CODEB_BLANK | MAX7219_CODEB_ADD_DECPOINT);
+        MAX7219_set_digit(display, 1, MAX7219_CODEB_BLANK | MAX7219_CODEB_ADD_DECPOINT);
+        MAX7219_set_digit(display, 0, MAX7219_CODEB_BLANK | MAX7219_CODEB_ADD_DECPOINT);
+
+        MAX7219_set_brightness(display, MAX7219_BRIGHTNESS_MAX);
+
+        Delay_Ms(34); //~30FPS
+
+        for (size_t intensitycycles = 0; intensitycycles < 4; intensitycycles++)
+        {
+            size_t intensity = 0x0E;
+
+            while (intensity > 0x00)
+            {
+                MAX7219_set_brightness(display, intensity);
+
+                intensity--;
+
+                Delay_Ms(34); //~30FPS
+            }
+
+            while (intensity < 0x0F)
+            {
+                MAX7219_set_brightness(display, intensity);
+                
+                //Move onto the next position
+                intensity++;
+
+                Delay_Ms(34); //~30FPS
+            }
+        }
+        #endif
+
+        #ifdef DEMO_INTENSITY_FADE_DIGITS
+        //Numeric intensity fade effect
+        MAX7219_set_decode_mode(display, MAX7219_DECODE_MODE_ALL);
+
+        MAX7219_set_digit(display, 7, MAX7219_CODEB_0);
+        MAX7219_set_digit(display, 6, MAX7219_CODEB_1);
+        MAX7219_set_digit(display, 5, MAX7219_CODEB_2);
+        MAX7219_set_digit(display, 4, MAX7219_CODEB_3);
+        MAX7219_set_digit(display, 3, MAX7219_CODEB_4);
+        MAX7219_set_digit(display, 2, MAX7219_CODEB_5);
+        MAX7219_set_digit(display, 1, MAX7219_CODEB_6);
+        MAX7219_set_digit(display, 0, MAX7219_CODEB_7);
+
+        MAX7219_set_brightness(display, MAX7219_BRIGHTNESS_MAX);
+
+        Delay_Ms(34); //~30FPS
+
+        for (size_t intensitycycles = 0; intensitycycles < 4; intensitycycles++)
+        {
+            size_t intensity = 0x0E;
+
+            while (intensity > 0x00)
+            {
+                MAX7219_set_brightness(display, intensity);
+
+                intensity--;
+
+                Delay_Ms(34); //~30FPS
+            }
+
+            while (intensity < 0x0F)
+            {
+                MAX7219_set_brightness(display, intensity);
+                
+                //Move onto the next position
+                intensity++;
+
+                Delay_Ms(34); //~30FPS
+            }
+        }
+        #endif
+
+        #ifdef DEMO_LED_CHASE
+        //Spinny LED chase effect using raw segment control
+        MAX7219_reset(display);
+
+        MAX7219_set_decode_mode(display, MAX7219_DECODE_MODE_NONE);
+
+        MAX7219_set_digit(display, 7, MAX7219_EXTFONT_BLANK);
+        MAX7219_set_digit(display, 6, MAX7219_EXTFONT_BLANK);
+        MAX7219_set_digit(display, 5, MAX7219_EXTFONT_BLANK);
+        MAX7219_set_digit(display, 4, MAX7219_EXTFONT_BLANK);
+        MAX7219_set_digit(display, 3, MAX7219_EXTFONT_BLANK);
+        MAX7219_set_digit(display, 2, MAX7219_EXTFONT_BLANK);
+        MAX7219_set_digit(display, 1, MAX7219_EXTFONT_BLANK);
+        MAX7219_set_digit(display, 0, MAX7219_EXTFONT_BLANK);
+
+        for (size_t chasecycles = 0; chasecycles < 8; chasecycles++)
+        {
+            MAX7219_set_digit(display, 7, MAX7219_SEGMENT_A);
+            Delay_Ms(34); //~30FPS
+
+            MAX7219_set_digit(display, 7, MAX7219_EXTFONT_BLANK);
+            MAX7219_set_digit(display, 6, MAX7219_SEGMENT_A);
+            Delay_Ms(34); //~30FPS
+
+            MAX7219_set_digit(display, 6, MAX7219_EXTFONT_BLANK);
+            MAX7219_set_digit(display, 5, MAX7219_SEGMENT_A);
+            Delay_Ms(34); //~30FPS
+
+            MAX7219_set_digit(display, 5, MAX7219_EXTFONT_BLANK);
+            MAX7219_set_digit(display, 4, MAX7219_SEGMENT_A);
+            Delay_Ms(34); //~30FPS
+
+            MAX7219_set_digit(display, 4, MAX7219_EXTFONT_BLANK);
+            MAX7219_set_digit(display, 3, MAX7219_SEGMENT_A);
+            Delay_Ms(34); //~30FPS
+
+            MAX7219_set_digit(display, 3, MAX7219_EXTFONT_BLANK);
+            MAX7219_set_digit(display, 2, MAX7219_SEGMENT_A);
+            Delay_Ms(34); //~30FPS
+
+            MAX7219_set_digit(display, 2, MAX7219_EXTFONT_BLANK);
+            MAX7219_set_digit(display, 1, MAX7219_SEGMENT_A);
+            Delay_Ms(34); //~30FPS
+
+            MAX7219_set_digit(display, 1, MAX7219_EXTFONT_BLANK);
+            MAX7219_set_digit(display, 0, MAX7219_SEGMENT_A);
+            Delay_Ms(34); //~30FPS
+
+            MAX7219_set_digit(display, 0, MAX7219_SEGMENT_B);
+            Delay_Ms(34); //~30FPS
+
+            MAX7219_set_digit(display, 0, MAX7219_SEGMENT_C);
+            Delay_Ms(34); //~30FPS
+
+            MAX7219_set_digit(display, 0, MAX7219_SEGMENT_D);
+            Delay_Ms(34); //~30FPS
+
+            MAX7219_set_digit(display, 0, MAX7219_EXTFONT_BLANK);
+            MAX7219_set_digit(display, 1, MAX7219_SEGMENT_D);
+            Delay_Ms(34); //~30FPS
+
+            MAX7219_set_digit(display, 1, MAX7219_EXTFONT_BLANK);
+            MAX7219_set_digit(display, 2, MAX7219_SEGMENT_D);
+            Delay_Ms(34); //~30FPS
+
+            MAX7219_set_digit(display, 2, MAX7219_EXTFONT_BLANK);
+            MAX7219_set_digit(display, 3, MAX7219_SEGMENT_D);
+            Delay_Ms(34); //~30FPS
+
+            MAX7219_set_digit(display, 3, MAX7219_EXTFONT_BLANK);
+            MAX7219_set_digit(display, 4, MAX7219_SEGMENT_D);
+            Delay_Ms(34); //~30FPS
+
+            MAX7219_set_digit(display, 4, MAX7219_EXTFONT_BLANK);
+            MAX7219_set_digit(display, 5, MAX7219_SEGMENT_D);
+            Delay_Ms(34); //~30FPS
+
+            MAX7219_set_digit(display, 5, MAX7219_EXTFONT_BLANK);
+            MAX7219_set_digit(display, 6, MAX7219_SEGMENT_D);
+            Delay_Ms(34); //~30FPS
+
+            MAX7219_set_digit(display, 6, MAX7219_EXTFONT_BLANK);
+            MAX7219_set_digit(display, 7, MAX7219_SEGMENT_D);
+            Delay_Ms(34); //~30FPS
+
+            MAX7219_set_digit(display, 7, MAX7219_SEGMENT_E);
+            Delay_Ms(34); //~30FPS
+
+            MAX7219_set_digit(display, 7, MAX7219_SEGMENT_F);
+            Delay_Ms(34); //~30FPS
+        }
+        #endif
+    }
+}
diff --git a/extralibs/ch32v003_SPI.h b/extralibs/ch32v003_SPI.h
index d29e6b42781fc226c914717b8403afba07e333d1..69a7e6a0edbb914651a4c4369da60b18b7242305 100644
--- a/extralibs/ch32v003_SPI.h
+++ b/extralibs/ch32v003_SPI.h
@@ -333,7 +333,13 @@ static inline uint8_t SPI_is_RX_empty() {
 static inline void SPI_wait_RX_available() {
 	while(!(SPI1->STATR & SPI_STATR_RXNE)) {}
 }
-
+static inline void SPI_wait_not_busy() {
+	while((SPI1->STATR & SPI_STATR_BSY) != 0) {}
+}
+static inline void SPI_wait_transmit_finished() {
+	SPI_wait_TX_complete();
+	SPI_wait_not_busy();
+}
 
 
 //######## implementation block