Maple Bootloader 2.0

Discussion about the Maple and other bootloaders
User avatar
RogerClark
Posts: 5891
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: Maple Bootloader 2.0

Post by RogerClark » Tue Jun 30, 2015 12:15 pm

Ray,

It should still work if they select the old bootloader, they just don't get the benefit unless they select the new one.

Actually on OSX and Linux the instant benefit is much faster uploads (though I'm not sure why this is, as it was something that had already been addressed in the code that we found, i.e an enhanced version of the original leaflabs version)

User avatar
mrburnette
Posts: 1783
Joined: Mon Apr 27, 2015 12:50 pm
Location: Greater Atlanta
Contact:

Re: Maple Bootloader 2.0

Post by mrburnette » Tue Jun 30, 2015 12:31 pm

RogerClark wrote:Ray,

It should still work if they select the old bootloader, they just don't get the benefit unless they select the new one.

Actually on OSX and Linux the instant benefit is much faster uploads (though I'm not sure why this is, as it was something that had already been addressed in the code that we found, i.e an enhanced version of the original leaflabs version)

Roger:
Honestly, I have never tried the "normal' setting on my modified-mini... I only upgraded the bootloader for the additional SRAM. But, it is good-news indeed that using the 'inappropriate, mismatched' setting does nothing rude, crude, or damaging.

Arduino 8-bit stuff gave me a great deal of over-confidence which the 32-bit PSoC system took away and rendered a new view of trashing hardware with improper settings! The STM32 under Arduino is somewhere between the two... generally works and hardware damage from misguided software configurations unlikely :) all good stuff!

Now, to the very dangerous end of the spectrum is the ESP8266 which (in my weeks of playing) seems to be a rather fragile beast. Improper loading or sometimes even proper uploading seems to completely go askew. It's baffling!


Ray

User avatar
tekk
Posts: 5
Joined: Mon Jun 22, 2015 8:24 pm
Location: Slovakia
Contact:

Re: Maple Bootloader 2.0

Post by tekk » Wed Jul 01, 2015 6:26 am

mrburnette wrote:
RogerClark wrote: Honestly, I have never tried the "normal' setting on my modified-mini... I only upgraded the bootloader for the additional SRAM.
Exactly my point.
I'm able to upload any sketch using the the old bootloader, just want to try 2.0.
Thanks for pointing me to the updater, Roger.

As for me, Bootloader 2.0 setting didn't work at the first time, I had to upload new sketch using Original settings and then the Bootloader 2.0 option seemed to start working.

So for anyone reading this, just upload this sketch:

Code: Select all

/**
 *
 * Maple Mini bootloader updater sketch.
 * Based on sketch from Gregwar for Robotis OpenCM9.04, which is based on Maple bootloader code.
 *
 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
 * WARNING                                                                 WARNING
 * WARNING  This comes with NO WARRANTY, you use it at your own risk       WARNING
 * WARNING                                                                 WARNING
 * WARNING  Please read this warning text and the instructions below       WARNING
 * WARNING                                                                 WARNING
 * WARNING  Running this sketch will erase your bootloader replace it      WARNING
 * WARNING  with the new STM32duino bootloader                             WARNING
 * WARNING                                                                 WARNING
 * WARNING  Only use this sketch with Maple mini boards.                   WARNING
 * WARNING                                                                 WARNING
 * WARNING  Note. If your bootloader does get messed up, it is possible    WARNING
 * WARNING  to reflash using an external USB to Serial adaptor or another  WARNING
 * WARNING  Arduino board (to act as a USB to Serial device)               WARNING
 * WARNING                                                                 WARNING
 * WARNING  For more information see www.stm32duino.com                    WARNING
 * WARNING                                                                 WARNING
 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
 *
 *
 * Instructions.
 * 
 * Upload this sketch onto your Maple mini.
 * 
 * After upload the LED on the board should start to flash slowly (on for 1 sec off for 1 sec)
 * 
 * Open the Serial Monitor and follow the on screen instructions
 * 
 * If the version of the bootloader that is contained in this sketch is already installed,
 * a message is displayed and you will not be prompted to update.
 * 
 * If prompted to update, press Y to agree and reflash the bootloader
 *
 * After the update has finished, the sketch will wait for you to manually reset the board
 * or to upload a new sketch
 * 
 * If you just reset the board. This sketch will run again, as it will not be touched by the bootloader update
 * However it will display the message to indicate that this bootloader has already been installed
 * 
 * For support please register to www.stm32duino.com
 * 
 * Credit goes to Victor PV, Matthis, Ray.
 * 
 * For source code and binaries for the bootloader see 
 * www.github.com/rogerclarkmelbourne/stm32duino-bootloader
 *
 * See also www.rogerclark.net 
 *
 */

// Data of bootloader
const char  maple_mini_boot20[7100] = {
  0x00, 0x50, 0x00, 0x20, 0x6D, 0x01, 0x00, 0x08, 0xB5, 0x01, 0x00, 0x08, 0xB5, 0x01, 0x00, 0x08,
  0xB5, 0x01, 0x00, 0x08, 0xB5, 0x01, 0x00, 0x08, 0xB5, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB5, 0x01, 0x00, 0x08,
  0xB5, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0xB5, 0x01, 0x00, 0x08, 0xB5, 0x01, 0x00, 0x08,
  0xB5, 0x01, 0x00, 0x08, 0xB5, 0x01, 0x00, 0x08, 0xB5, 0x01, 0x00, 0x08, 0xB5, 0x01, 0x00, 0x08,
  0xB5, 0x01, 0x00, 0x08, 0xB5, 0x01, 0x00, 0x08, 0xB5, 0x01, 0x00, 0x08, 0xB5, 0x01, 0x00, 0x08,
  0xB5, 0x01, 0x00, 0x08, 0xB5, 0x01, 0x00, 0x08, 0xB5, 0x01, 0x00, 0x08, 0xB5, 0x01, 0x00, 0x08,
  0xB5, 0x01, 0x00, 0x08, 0xB5, 0x01, 0x00, 0x08, 0xB5, 0x01, 0x00, 0x08, 0xB5, 0x01, 0x00, 0x08,
  0xB5, 0x01, 0x00, 0x08, 0xB5, 0x01, 0x00, 0x08, 0xB5, 0x01, 0x00, 0x08, 0xB5, 0x01, 0x00, 0x08,
  0x39, 0x05, 0x00, 0x08, 0xB5, 0x01, 0x00, 0x08, 0xB5, 0x01, 0x00, 0x08, 0xB5, 0x01, 0x00, 0x08,
  0xB5, 0x01, 0x00, 0x08, 0xB5, 0x01, 0x00, 0x08, 0xB5, 0x01, 0x00, 0x08, 0xB5, 0x01, 0x00, 0x08,
  0xB5, 0x01, 0x00, 0x08, 0xB5, 0x01, 0x00, 0x08, 0xB5, 0x01, 0x00, 0x08, 0xB5, 0x01, 0x00, 0x08,
  0xB5, 0x01, 0x00, 0x08, 0xB5, 0x01, 0x00, 0x08, 0xB5, 0x01, 0x00, 0x08, 0xB5, 0x01, 0x00, 0x08,
  0xB5, 0x01, 0x00, 0x08, 0xB5, 0x01, 0x00, 0x08, 0xB5, 0x01, 0x00, 0x08, 0xB5, 0x01, 0x00, 0x08,
  0xB5, 0x01, 0x00, 0x08, 0xB5, 0x01, 0x00, 0x08, 0xB5, 0x01, 0x00, 0x08, 0x5F, 0xF8, 0x08, 0xF1,
  0x30, 0xBF, 0x70, 0x47, 0x20, 0xBF, 0x70, 0x47, 0x40, 0xBF, 0x70, 0x47, 0xBF, 0xF3, 0x6F, 0x8F,
  0x70, 0x47, 0xBF, 0xF3, 0x4F, 0x8F, 0x70, 0x47, 0xBF, 0xF3, 0x5F, 0x8F, 0x70, 0x47, 0x01, 0xDF,
  0x70, 0x47, 0xEF, 0xF3, 0x14, 0x80, 0x70, 0x47, 0x80, 0xF3, 0x14, 0x88, 0xBF, 0xF3, 0x6F, 0x8F,
  0x70, 0x47, 0xEF, 0xF3, 0x09, 0x80, 0x70, 0x47, 0x80, 0xF3, 0x09, 0x88, 0x70, 0x47, 0xEF, 0xF3,
  0x08, 0x80, 0x70, 0x47, 0x80, 0xF3, 0x08, 0x88, 0x70, 0x47, 0x62, 0xB6, 0x70, 0x47, 0x72, 0xB6,
  0x70, 0x47, 0xEF, 0xF3, 0x10, 0x80, 0x70, 0x47, 0x61, 0xB6, 0x70, 0x47, 0x71, 0xB6, 0x70, 0x47,
  0xEF, 0xF3, 0x13, 0x80, 0x70, 0x47, 0x80, 0xF3, 0x11, 0x88, 0x70, 0x47, 0xEF, 0xF3, 0x12, 0x80,
  0x70, 0x47, 0x40, 0xBA, 0x70, 0x47, 0x00, 0xBA, 0x70, 0x47, 0x00, 0x00, 0x00, 0x21, 0x00, 0xF0,
  0x04, 0xB8, 0x0B, 0x4B, 0x5B, 0x58, 0x43, 0x50, 0x04, 0x31, 0x0A, 0x48, 0x0A, 0x4B, 0x42, 0x18,
  0x9A, 0x42, 0xFF, 0xF4, 0xF6, 0xAF, 0x09, 0x4A, 0x00, 0xF0, 0x03, 0xB8, 0x00, 0x23, 0x42, 0xF8,
  0x04, 0x3B, 0x07, 0x4B, 0x9A, 0x42, 0xFF, 0xF4, 0xF9, 0xAF, 0x00, 0xF0, 0x27, 0xFA, 0x70, 0x47,
  0xB4, 0x18, 0x00, 0x08, 0x00, 0x00, 0x00, 0x20, 0x08, 0x03, 0x00, 0x20, 0x08, 0x03, 0x00, 0x20,
  0x4C, 0x03, 0x00, 0x20, 0xFF, 0xF7, 0xFE, 0xBF, 0x70, 0x47, 0x70, 0x47, 0x70, 0x47, 0x03, 0x28,
  0x8C, 0xBF, 0x02, 0x20, 0x00, 0x20, 0x70, 0x47, 0x70, 0x47, 0x00, 0x00, 0x03, 0x4B, 0x1B, 0x68,
  0x9B, 0x7A, 0x13, 0xB1, 0x02, 0x4B, 0x05, 0x22, 0x1A, 0x60, 0x70, 0x47, 0x44, 0x03, 0x00, 0x20,
  0x50, 0x03, 0x00, 0x20, 0x70, 0x47, 0x70, 0x47, 0x70, 0x47, 0x70, 0x47, 0x70, 0x47, 0x70, 0x47,
  0x01, 0x4B, 0x04, 0x22, 0x1A, 0x60, 0x70, 0x47, 0x50, 0x03, 0x00, 0x20, 0x10, 0xB5, 0x00, 0xF0,
  0x0F, 0xFC, 0x21, 0x4B, 0x21, 0x4A, 0x1B, 0x68, 0x00, 0x24, 0x12, 0x68, 0x9C, 0x72, 0xD2, 0x79,
  0x20, 0x46, 0x5A, 0x72, 0x1E, 0x4A, 0x1F, 0x4B, 0x14, 0x60, 0x19, 0x68, 0x21, 0xF4, 0xEC, 0x41,
  0x21, 0xF0, 0x70, 0x01, 0x41, 0xF4, 0x00, 0x71, 0x89, 0xB2, 0x19, 0x60, 0x19, 0x68, 0x21, 0xF4,
  0xE0, 0x41, 0x21, 0xF0, 0x40, 0x01, 0x89, 0xB2, 0x81, 0xF0, 0x10, 0x01, 0x19, 0x60, 0x11, 0x68,
  0x15, 0x4B, 0x89, 0xB2, 0x0B, 0x44, 0x5B, 0x00, 0x40, 0x21, 0x19, 0x60, 0x13, 0x68, 0x80, 0x22,
  0x9B, 0xB2, 0x03, 0xF1, 0x00, 0x53, 0x03, 0xF5, 0x40, 0x53, 0x5B, 0x00, 0x1A, 0x60, 0x00, 0xF0,
  0xBB, 0xFD, 0x0E, 0x4B, 0x20, 0x46, 0x1B, 0x68, 0x93, 0xF8, 0x30, 0x10, 0x00, 0xF0, 0x0C, 0xFE,
  0x20, 0x46, 0x00, 0xF0, 0xA2, 0xFD, 0x0A, 0x4B, 0x01, 0x22, 0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40,
  0x1A, 0x60, 0x01, 0xF0, 0xA3, 0xBA, 0x00, 0xBF, 0x44, 0x03, 0x00, 0x20, 0xF8, 0x02, 0x00, 0x20,
  0x50, 0x5C, 0x00, 0x40, 0x00, 0x5C, 0x00, 0x40, 0x04, 0x30, 0x00, 0x20, 0x1C, 0x03, 0x00, 0x20,
  0x50, 0x03, 0x00, 0x20, 0x38, 0xB5, 0x12, 0x4B, 0x05, 0x46, 0x1A, 0x68, 0x1C, 0x46, 0x12, 0x78,
  0x02, 0xF0, 0x7F, 0x02, 0x21, 0x2A, 0x19, 0xD1, 0x00, 0xF0, 0x48, 0xFC, 0xB0, 0xB1, 0x68, 0x1E,
  0x04, 0x28, 0x13, 0xD8, 0xDF, 0xE8, 0x00, 0xF0, 0x03, 0x05, 0x07, 0x12, 0x09, 0x00, 0x09, 0x4B,
  0x04, 0xE0, 0x09, 0x4B, 0x02, 0xE0, 0x09, 0x4B, 0x00, 0xE0, 0x09, 0x4B, 0x22, 0x68, 0x00, 0x24,
  0x20, 0x46, 0x93, 0x61, 0x54, 0x82, 0x98, 0x47, 0x20, 0x46, 0x38, 0xBD, 0x02, 0x20, 0x38, 0xBD,
  0x44, 0x03, 0x00, 0x20, 0x95, 0x0A, 0x00, 0x08, 0xBD, 0x0A, 0x00, 0x08, 0x7D, 0x0A, 0x00, 0x08,
  0x65, 0x0A, 0x00, 0x08, 0x01, 0x49, 0x01, 0xF0, 0x61, 0xB8, 0x00, 0xBF, 0x44, 0x01, 0x00, 0x20,
  0x01, 0x49, 0x01, 0xF0, 0x5B, 0xB8, 0x00, 0xBF, 0xF8, 0x02, 0x00, 0x20, 0x05, 0x4B, 0x1B, 0x68,
  0x9B, 0x78, 0x07, 0x2B, 0x04, 0xD8, 0x04, 0x49, 0x01, 0xEB, 0xC3, 0x01, 0x01, 0xF0, 0x4E, 0xB8,
  0x00, 0x20, 0x70, 0x47, 0x44, 0x03, 0x00, 0x20, 0x94, 0x00, 0x00, 0x20, 0x01, 0x49, 0x01, 0xF0,
  0x45, 0xB8, 0x00, 0xBF, 0xE0, 0x00, 0x00, 0x20, 0x08, 0xB5, 0x08, 0x4B, 0x1B, 0x68, 0x1B, 0x78,
  0x03, 0xF0, 0x7F, 0x03, 0x21, 0x2B, 0x06, 0xD1, 0x00, 0xF0, 0xF8, 0xFB, 0x00, 0x28, 0x0C, 0xBF,
  0x02, 0x20, 0x00, 0x20, 0x08, 0xBD, 0x02, 0x20, 0x08, 0xBD, 0x00, 0xBF, 0x44, 0x03, 0x00, 0x20,
  0x38, 0xB5, 0x13, 0x4C, 0x09, 0x20, 0x25, 0x68, 0x00, 0xF0, 0x06, 0xFB, 0x28, 0x40, 0x40, 0xF0,
  0x50, 0x05, 0x25, 0x60, 0x04, 0x3C, 0x20, 0x46, 0x09, 0x21, 0x01, 0x22, 0x00, 0xF0, 0x88, 0xF9,
  0x20, 0x46, 0x00, 0x22, 0x09, 0x21, 0x00, 0xF0, 0x83, 0xF9, 0x00, 0xF0, 0x07, 0xFB, 0x09, 0x4B,
  0xC2, 0xB2, 0x18, 0x60, 0x08, 0x4B, 0xC0, 0xF3, 0x07, 0x20, 0x83, 0xF8, 0x29, 0x20, 0x83, 0xF8,
  0x2A, 0x00, 0x06, 0x4B, 0x5A, 0x71, 0x98, 0x71, 0xBD, 0xE8, 0x38, 0x40, 0x00, 0xF0, 0x2E, 0xBE,
  0x04, 0x0C, 0x01, 0x40, 0x08, 0x03, 0x00, 0x20, 0xEC, 0x00, 0x00, 0x20, 0x29, 0x01, 0x00, 0x20,
  0x04, 0x4B, 0x1A, 0x68, 0x92, 0xB2, 0x42, 0xF0, 0x0C, 0x02, 0x1A, 0x60, 0x02, 0x4B, 0x03, 0x22,
  0x1A, 0x60, 0x70, 0x47, 0x40, 0x5C, 0x00, 0x40, 0x50, 0x03, 0x00, 0x20, 0x04, 0x4B, 0x4F, 0xF6,
  0xFB, 0x72, 0x19, 0x68, 0x0A, 0x40, 0x1A, 0x60, 0x4F, 0xF4, 0x3F, 0x42, 0x1A, 0x60, 0x70, 0x47,
  0x40, 0x5C, 0x00, 0x40, 0x10, 0xB5, 0x1E, 0x4C, 0x07, 0x28, 0x18, 0xBF, 0x20, 0x70, 0x23, 0x78,
  0x05, 0x2B, 0x32, 0xD8, 0xDF, 0xE8, 0x03, 0xF0, 0x03, 0x06, 0x0A, 0x0E, 0x16, 0x21, 0xFF, 0xF7,
  0xE5, 0xFF, 0x2A, 0xE0, 0xFF, 0xF7, 0xE2, 0xFF, 0x04, 0x23, 0x27, 0xE0, 0x02, 0x23, 0x63, 0x70,
  0x03, 0x23, 0x23, 0xE0, 0x63, 0x78, 0x01, 0x3B, 0xDB, 0xB2, 0x63, 0x70, 0x63, 0x78, 0xF3, 0xB9,
  0x04, 0x22, 0x17, 0xE0, 0x0F, 0x4B, 0x1A, 0x68, 0x92, 0xB2, 0x42, 0xF0, 0x10, 0x02, 0x1A, 0x60,
  0x05, 0x23, 0x23, 0x70, 0x0A, 0x23, 0x63, 0x70, 0x10, 0xBD, 0x63, 0x78, 0x01, 0x3B, 0xDB, 0xB2,
  0x63, 0x70, 0x63, 0x78, 0x5B, 0xB9, 0x07, 0x4A, 0x4F, 0xF6, 0xEF, 0x73, 0x11, 0x68, 0x0B, 0x40,
  0x13, 0x60, 0x06, 0x22, 0x02, 0x4B, 0x1A, 0x70, 0x10, 0xBD, 0x06, 0x23, 0x23, 0x70, 0x10, 0xBD,
  0x0E, 0x03, 0x00, 0x20, 0x40, 0x5C, 0x00, 0x40, 0x06, 0x4B, 0x01, 0x22, 0x1A, 0x60, 0x06, 0x4A,
  0x00, 0x20, 0x06, 0x49, 0x18, 0x60, 0x10, 0x60, 0x4F, 0xF4, 0xE0, 0x52, 0x0A, 0x80, 0x1A, 0x60,
  0x70, 0x47, 0x00, 0xBF, 0x40, 0x5C, 0x00, 0x40, 0x44, 0x5C, 0x00, 0x40, 0x48, 0x03, 0x00, 0x20,
  0x07, 0xB5, 0x14, 0x23, 0x8D, 0xF8, 0x04, 0x30, 0x00, 0x23, 0x8D, 0xF8, 0x05, 0x30, 0x8D, 0xF8,
  0x06, 0x30, 0x01, 0xA8, 0x01, 0x23, 0x8D, 0xF8, 0x07, 0x30, 0x00, 0xF0, 0xA5, 0xF9, 0x03, 0xB0,
  0x5D, 0xF8, 0x04, 0xFB, 0x10, 0xB5, 0x00, 0xF0, 0x75, 0xFA, 0x09, 0x4B, 0x00, 0x24, 0x1B, 0x68,
  0x9C, 0x72, 0xFF, 0xF7, 0xD1, 0xFF, 0x07, 0x4B, 0x07, 0x4A, 0x1C, 0x60, 0x4F, 0xF4, 0x3F, 0x43,
  0x13, 0x80, 0x06, 0x4A, 0x13, 0x60, 0xFF, 0xF7, 0xDB, 0xFF, 0x05, 0x4B, 0x1C, 0x60, 0x10, 0xBD,
  0x44, 0x03, 0x00, 0x20, 0x44, 0x5C, 0x00, 0x40, 0x48, 0x03, 0x00, 0x20, 0x40, 0x5C, 0x00, 0x40,
  0x50, 0x03, 0x00, 0x20, 0x07, 0xB5, 0x14, 0x23, 0x8D, 0xF8, 0x04, 0x30, 0x01, 0xA8, 0x00, 0x23,
  0x8D, 0xF8, 0x05, 0x30, 0x8D, 0xF8, 0x06, 0x30, 0x8D, 0xF8, 0x07, 0x30, 0x00, 0xF0, 0x74, 0xF9,
  0x03, 0xB0, 0x5D, 0xF8, 0x04, 0xFB, 0x00, 0x00, 0x70, 0xB5, 0x27, 0x4D, 0x27, 0x4C, 0x2B, 0x68,
  0x27, 0x4E, 0x9B, 0xB2, 0x23, 0x80, 0x22, 0x88, 0x33, 0x88, 0x13, 0x40, 0x59, 0x05, 0x05, 0xD5,
  0x4F, 0xF6, 0xFF, 0x33, 0x2B, 0x60, 0x23, 0x4B, 0x5B, 0x68, 0x98, 0x47, 0x22, 0x88, 0x33, 0x88,
  0x1A, 0x40, 0x92, 0x04, 0x44, 0xBF, 0x4D, 0xF6, 0xFF, 0x72, 0x2A, 0x60, 0x22, 0x88, 0x13, 0x40,
  0xDB, 0x04, 0x05, 0xD5, 0x4E, 0xF6, 0xFF, 0x73, 0x2B, 0x60, 0x00, 0x20, 0xFF, 0xF7, 0x42, 0xFF,
  0x22, 0x88, 0x33, 0x88, 0x13, 0x40, 0x18, 0x05, 0x04, 0xD5, 0xFF, 0xF7, 0x21, 0xFF, 0x4F, 0xF2,
  0xFF, 0x73, 0x2B, 0x60, 0x22, 0x88, 0x33, 0x88, 0x1A, 0x40, 0x91, 0x05, 0x07, 0xD5, 0x4F, 0xF6,
  0xFF, 0x52, 0x2A, 0x60, 0x10, 0x4A, 0x11, 0x78, 0x01, 0x31, 0xC9, 0xB2, 0x11, 0x70, 0x22, 0x88,
  0x13, 0x40, 0xDA, 0x05, 0x05, 0xD5, 0x4F, 0xF6, 0xFF, 0x63, 0x2B, 0x60, 0x07, 0x20, 0xFF, 0xF7,
  0x21, 0xFF, 0x22, 0x88, 0x33, 0x88, 0x13, 0x40, 0x1B, 0x04, 0x03, 0xD5, 0xBD, 0xE8, 0x70, 0x40,
  0x00, 0xF0, 0x7A, 0xBC, 0x70, 0xBD, 0x00, 0xBF, 0x44, 0x5C, 0x00, 0x40, 0x0C, 0x03, 0x00, 0x20,
  0x48, 0x03, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x4C, 0x03, 0x00, 0x20, 0x37, 0xB5, 0x01, 0x24,
  0x00, 0xF0, 0x92, 0xF8, 0x00, 0xF0, 0xB4, 0xF8, 0x00, 0xF0, 0xE2, 0xF8, 0xFF, 0xF7, 0xB8, 0xFE,
  0x00, 0xF0, 0xF2, 0xF8, 0x23, 0x48, 0x00, 0x94, 0x21, 0x46, 0x05, 0x22, 0x4F, 0xF4, 0xA0, 0x23,
  0x00, 0xF0, 0x5A, 0xF8, 0x20, 0x48, 0x00, 0xF0, 0xF5, 0xF8, 0x28, 0xB1, 0x00, 0xF0, 0x4C, 0xF8,
  0x00, 0x30, 0x18, 0xBF, 0x01, 0x20, 0x05, 0xE0, 0x1C, 0x48, 0x00, 0xF0, 0xEB, 0xF8, 0x00, 0x28,
  0xF4, 0xD1, 0x20, 0x46, 0xC4, 0xB2, 0x00, 0x25, 0x05, 0x2D, 0x0E, 0xDC, 0x01, 0x21, 0x00, 0x91,
  0x14, 0x48, 0x0A, 0x46, 0x4F, 0xF4, 0x80, 0x13, 0x00, 0xF0, 0x3E, 0xF8, 0x00, 0xF0, 0x98, 0xFB,
  0x08, 0xB1, 0x00, 0xF0, 0x9B, 0xFB, 0x01, 0x35, 0xEE, 0xE7, 0x00, 0x2C, 0xEE, 0xD1, 0x0F, 0x48,
  0x00, 0xF0, 0xD0, 0xF8, 0x08, 0xB1, 0x0D, 0x48, 0x04, 0xE0, 0x0B, 0x48, 0x00, 0xF0, 0xCA, 0xF8,
  0x18, 0xB1, 0x09, 0x48, 0x00, 0xF0, 0x18, 0xF9, 0x09, 0xE0, 0x01, 0x21, 0x00, 0x91, 0x05, 0x48,
  0x05, 0x22, 0x4F, 0xF4, 0xA0, 0x23, 0x00, 0xF0, 0x1F, 0xF8, 0x00, 0xF0, 0x21, 0xF9, 0x00, 0x20,
  0x03, 0xB0, 0x30, 0xBD, 0x00, 0x0C, 0x01, 0x40, 0x00, 0x50, 0x00, 0x08, 0x00, 0x20, 0x00, 0x08,
  0x01, 0x23, 0x03, 0xFA, 0x01, 0xF1, 0xD2, 0xF1, 0x01, 0x02, 0x38, 0xBF, 0x00, 0x22, 0x13, 0x01,
  0x99, 0x40, 0x01, 0x61, 0x70, 0x47, 0x00, 0x00, 0x02, 0x4B, 0x18, 0x68, 0xC0, 0xF3, 0x00, 0x20,
  0x70, 0x47, 0x00, 0xBF, 0x08, 0x0C, 0x01, 0x40, 0x2D, 0xE9, 0xF0, 0x47, 0x9D, 0xF8, 0x20, 0xA0,
  0x14, 0x46, 0xCA, 0xF1, 0x01, 0x07, 0xFF, 0xB2, 0x3A, 0x46, 0x80, 0x46, 0x89, 0x46, 0x1E, 0x46,
  0xFF, 0xF7, 0xDE, 0xFF, 0xB4, 0xB1, 0x35, 0x46, 0x15, 0xB1, 0x00, 0xBF, 0x01, 0x3D, 0xFB, 0xE7,
  0x40, 0x46, 0x49, 0x46, 0x52, 0x46, 0xFF, 0xF7, 0xD3, 0xFF, 0x35, 0x46, 0x15, 0xB1, 0x00, 0xBF,
  0x01, 0x3D, 0xFB, 0xE7, 0x40, 0x46, 0x49, 0x46, 0x3A, 0x46, 0x01, 0x3C, 0xFF, 0xF7, 0xC8, 0xFF,
  0xE4, 0xB2, 0xE7, 0xE7, 0xBD, 0xE8, 0xF0, 0x87, 0x0D, 0x4B, 0x0E, 0x49, 0x1A, 0x68, 0x42, 0xF0,
  0x01, 0x02, 0x1A, 0x60, 0x0C, 0x4A, 0x10, 0x68, 0x01, 0x40, 0x11, 0x60, 0x19, 0x68, 0x21, 0xF0,
  0x84, 0x71, 0x21, 0xF4, 0x80, 0x31, 0x19, 0x60, 0x19, 0x68, 0x21, 0xF4, 0x80, 0x21, 0x19, 0x60,
  0x13, 0x68, 0x23, 0xF4, 0xFE, 0x03, 0x13, 0x60, 0x04, 0x4B, 0x00, 0x22, 0x1A, 0x60, 0x70, 0x47,
  0x00, 0x10, 0x02, 0x40, 0x00, 0x00, 0xFF, 0xF8, 0x04, 0x10, 0x02, 0x40, 0x08, 0x10, 0x02, 0x40,
  0x15, 0x4B, 0x1A, 0x68, 0x42, 0xF0, 0x01, 0x12, 0x1A, 0x60, 0x1A, 0x68, 0x12, 0x48, 0x92, 0x03,
  0xFB, 0xD5, 0x12, 0x4A, 0x12, 0x21, 0x11, 0x60, 0xA2, 0xF6, 0xFC, 0x72, 0x11, 0x68, 0x41, 0xF4,
  0xE8, 0x11, 0x41, 0xF4, 0x80, 0x61, 0x11, 0x60, 0x01, 0x68, 0x41, 0xF0, 0x80, 0x71, 0x01, 0x60,
  0x19, 0x68, 0x11, 0xF0, 0x40, 0x7F, 0xFB, 0xD0, 0x11, 0x68, 0x41, 0xF0, 0x02, 0x01, 0x11, 0x60,
  0x11, 0x68, 0x09, 0x07, 0xFC, 0xD5, 0x9A, 0x69, 0x42, 0xF4, 0xFE, 0x72, 0x9A, 0x61, 0xDA, 0x69,
  0x42, 0xF4, 0x00, 0x02, 0xDA, 0x61, 0x70, 0x47, 0x00, 0x10, 0x02, 0x40, 0x00, 0x20, 0x02, 0x40,
  0x07, 0x4B, 0x08, 0x4A, 0x1A, 0x60, 0x4F, 0xF0, 0x80, 0x72, 0xDA, 0x60, 0x53, 0xF8, 0x04, 0x2C,
  0x22, 0xF0, 0xF0, 0x02, 0x42, 0xF0, 0x10, 0x02, 0x43, 0xF8, 0x04, 0x2C, 0x70, 0x47, 0x00, 0xBF,
  0x04, 0x0C, 0x01, 0x40, 0x08, 0x0C, 0x01, 0x40, 0x05, 0x4B, 0x1A, 0x68, 0xD1, 0x07, 0x03, 0xD4,
  0x1A, 0x68, 0x42, 0xF0, 0x01, 0x02, 0x1A, 0x60, 0x1A, 0x68, 0x92, 0x07, 0xFC, 0xD5, 0x70, 0x47,
  0x00, 0x10, 0x02, 0x40, 0x03, 0x68, 0x03, 0x48, 0x18, 0x40, 0xB0, 0xF1, 0x00, 0x53, 0x58, 0x42,
  0x58, 0x41, 0x70, 0x47, 0x00, 0x00, 0xFE, 0x2F, 0x18, 0x4B, 0x30, 0xB5, 0xDB, 0x68, 0x44, 0x78,
  0xDB, 0x43, 0xC3, 0xF3, 0x02, 0x23, 0xC3, 0xF1, 0x04, 0x02, 0x04, 0xFA, 0x02, 0xF2, 0x0F, 0x24,
  0xDC, 0x40, 0x81, 0x78, 0x03, 0x78, 0x0C, 0x40, 0x14, 0x43, 0x03, 0xF0, 0x03, 0x01, 0xC9, 0x00,
  0x24, 0x01, 0xFF, 0x22, 0x8C, 0x40, 0x8A, 0x40, 0x03, 0xF0, 0xFC, 0x03, 0x03, 0xF1, 0x60, 0x43,
  0x03, 0xF5, 0x61, 0x43, 0xD3, 0xF8, 0x00, 0x53, 0x25, 0xEA, 0x02, 0x01, 0x22, 0x40, 0x0A, 0x43,
  0xC3, 0xF8, 0x00, 0x23, 0x03, 0x78, 0x01, 0x22, 0x59, 0x09, 0x03, 0xF0, 0x1F, 0x03, 0x02, 0xFA,
  0x03, 0xF3, 0x03, 0x4A, 0x42, 0xF8, 0x21, 0x30, 0x30, 0xBD, 0x00, 0xBF, 0x00, 0xED, 0x00, 0xE0,
  0x00, 0xE1, 0x00, 0xE0, 0x07, 0x4B, 0x4F, 0xF0, 0xFF, 0x32, 0xC3, 0xF8, 0x80, 0x20, 0xC3, 0xF8,
  0x84, 0x20, 0xC3, 0xF8, 0x80, 0x21, 0xC3, 0xF8, 0x84, 0x21, 0x04, 0x22, 0x43, 0xF8, 0xF0, 0x2C,
  0x70, 0x47, 0x00, 0xBF, 0x00, 0xE1, 0x00, 0xE0, 0x38, 0xB5, 0x08, 0x4B, 0x80, 0x22, 0x45, 0x68,
  0x04, 0x46, 0x1A, 0x60, 0xFF, 0xF7, 0x2E, 0xFE, 0xFF, 0xF7, 0xE4, 0xFF, 0xFF, 0xF7, 0x2C, 0xFF,
  0x20, 0x68, 0xFF, 0xF7, 0x37, 0xFC, 0xA8, 0x47, 0x38, 0xBD, 0x00, 0xBF, 0x10, 0x20, 0x02, 0x40,
  0x02, 0x4A, 0x03, 0x4B, 0xDA, 0x60, 0x00, 0xBF, 0xFD, 0xE7, 0x00, 0xBF, 0x04, 0x00, 0xFA, 0x05,
  0x00, 0xED, 0x00, 0xE0, 0x0A, 0x4B, 0x10, 0xB5, 0x1A, 0x68, 0x02, 0x22, 0x1A, 0x60, 0x09, 0x4A,
  0x11, 0x68, 0x14, 0x46, 0x11, 0xF0, 0x01, 0x0F, 0xF9, 0xD1, 0x90, 0x60, 0x42, 0x22, 0x1A, 0x60,
  0x22, 0x68, 0x12, 0xF0, 0x01, 0x01, 0xFB, 0xD1, 0x19, 0x60, 0x01, 0x20, 0x10, 0xBD, 0x00, 0xBF,
  0x10, 0x20, 0x02, 0x40, 0x0C, 0x20, 0x02, 0x40, 0x37, 0xB5, 0x8B, 0xB2, 0x00, 0x93, 0x0B, 0x0C,
  0x01, 0x93, 0x0E, 0x4B, 0x01, 0x22, 0x1C, 0x68, 0x1A, 0x60, 0x0D, 0x4A, 0x15, 0x68, 0xED, 0x07,
  0xFB, 0xD4, 0x01, 0x9D, 0xAD, 0xB2, 0x45, 0x80, 0x15, 0x68, 0xED, 0x07, 0xFC, 0xD4, 0x00, 0x9D,
  0xAD, 0xB2, 0x05, 0x80, 0x15, 0x68, 0xED, 0x07, 0xFC, 0xD4, 0x24, 0xF0, 0x01, 0x02, 0x1A, 0x60,
  0x00, 0x68, 0x43, 0x1A, 0x58, 0x42, 0x58, 0x41, 0x03, 0xB0, 0x30, 0xBD, 0x10, 0x20, 0x02, 0x40,
  0x0C, 0x20, 0x02, 0x40, 0x01, 0x4B, 0x80, 0x22, 0x1A, 0x60, 0x70, 0x47, 0x10, 0x20, 0x02, 0x40,
  0x03, 0x4B, 0x04, 0x4A, 0x1A, 0x60, 0x02, 0xF1, 0x88, 0x32, 0x1A, 0x60, 0x70, 0x47, 0x00, 0xBF,
  0x04, 0x20, 0x02, 0x40, 0x23, 0x01, 0x67, 0x45, 0x07, 0x28, 0xC8, 0xBF, 0x08, 0x38, 0x0F, 0x23,
  0x80, 0x00, 0x03, 0xFA, 0x00, 0xF0, 0xC0, 0x43, 0x70, 0x47, 0x00, 0x00, 0x02, 0x4B, 0x18, 0x88,
  0x00, 0xF5, 0x00, 0x30, 0x80, 0x02, 0x70, 0x47, 0xE0, 0xF7, 0xFF, 0x1F, 0x04, 0x4B, 0x1B, 0x88,
  0x81, 0x2B, 0x34, 0xBF, 0x4F, 0xF4, 0x80, 0x60, 0x4F, 0xF4, 0x00, 0x60, 0x70, 0x47, 0x00, 0xBF,
  0xE0, 0xF7, 0xFF, 0x1F, 0x0D, 0x4A, 0x00, 0x23, 0x02, 0x21, 0x13, 0x70, 0x53, 0x70, 0x93, 0x70,
  0xD3, 0x70, 0x11, 0x71, 0x53, 0x71, 0x0A, 0x4A, 0x0A, 0x49, 0x13, 0x60, 0x0A, 0x4A, 0x13, 0x80,
  0x0A, 0x4A, 0x11, 0x60, 0x0A, 0x4A, 0x01, 0xF5, 0x88, 0x41, 0x11, 0x60, 0x09, 0x4A, 0x03, 0x21,
  0x13, 0x70, 0x09, 0x4A, 0x11, 0x70, 0x09, 0x4A, 0x13, 0x70, 0x70, 0x47, 0x5D, 0x0B, 0x00, 0x20,
  0x58, 0x0B, 0x00, 0x20, 0x00, 0x0C, 0x00, 0x20, 0x56, 0x0B, 0x00, 0x20, 0x04, 0x03, 0x00, 0x20,
  0x00, 0x03, 0x00, 0x20, 0x5C, 0x0B, 0x00, 0x20, 0x10, 0x03, 0x00, 0x20, 0x63, 0x0B, 0x00, 0x20,
  0x08, 0xB5, 0x0E, 0x4B, 0x0E, 0x48, 0x19, 0x79, 0x00, 0x22, 0xC9, 0xB2, 0x01, 0x29, 0x02, 0x60,
  0x08, 0xD1, 0x02, 0x21, 0x19, 0x71, 0x1A, 0x70, 0xFF, 0xF7, 0x24, 0xFF, 0xBD, 0xE8, 0x08, 0x40,
  0xFF, 0xF7, 0x36, 0xBD, 0x11, 0xF0, 0xFD, 0x0F, 0x06, 0xD0, 0x02, 0x21, 0x19, 0x71, 0x1A, 0x70,
  0xBD, 0xE8, 0x08, 0x40, 0xFF, 0xF7, 0x3C, 0xBF, 0x08, 0xBD, 0x00, 0xBF, 0x5D, 0x0B, 0x00, 0x20,
  0x58, 0x0B, 0x00, 0x20, 0x20, 0xB9, 0x03, 0x4B, 0x01, 0x22, 0x1B, 0x68, 0x1A, 0x82, 0x70, 0x47,
  0x01, 0x48, 0x70, 0x47, 0x44, 0x03, 0x00, 0x20, 0x61, 0x0B, 0x00, 0x20, 0x20, 0xB9, 0x03, 0x4B,
  0x06, 0x22, 0x1B, 0x68, 0x1A, 0x82, 0x70, 0x47, 0x01, 0x48, 0x70, 0x47, 0x44, 0x03, 0x00, 0x20,
  0x5D, 0x0B, 0x00, 0x20, 0x06, 0x4B, 0x1B, 0x68, 0x30, 0xB9, 0xDA, 0x88, 0x59, 0x8A, 0x51, 0x1A,
  0x19, 0x82, 0x04, 0x4B, 0x1A, 0x80, 0x70, 0x47, 0x5B, 0x8A, 0x03, 0x48, 0x18, 0x44, 0x70, 0x47,
  0x44, 0x03, 0x00, 0x20, 0x56, 0x0B, 0x00, 0x20, 0x54, 0x03, 0x00, 0x20, 0x08, 0x4B, 0x30, 0xB9,
  0x1B, 0x68, 0x08, 0x4A, 0x11, 0x88, 0x5A, 0x8A, 0x8A, 0x1A, 0x1A, 0x82, 0x70, 0x47, 0x06, 0x49,
  0x06, 0x4A, 0x1B, 0x68, 0x12, 0x68, 0x08, 0x68, 0x5B, 0x8A, 0x10, 0x44, 0x18, 0x44, 0x70, 0x47,
  0x44, 0x03, 0x00, 0x20, 0x56, 0x0B, 0x00, 0x20, 0x04, 0x03, 0x00, 0x20, 0x58, 0x0B, 0x00, 0x20,
  0x70, 0xB5, 0x12, 0x4B, 0x12, 0x4E, 0x1B, 0x78, 0x34, 0x68, 0x02, 0x2B, 0x04, 0xF1, 0x00, 0x64,
  0x0C, 0xBF, 0x04, 0xF5, 0xA0, 0x44, 0x04, 0xF5, 0x00, 0x54, 0x20, 0x46, 0xFF, 0xF7, 0xEA, 0xFE,
  0x00, 0x25, 0x0C, 0x4B, 0x1A, 0x88, 0x92, 0xB2, 0x95, 0x42, 0x06, 0xDA, 0x0A, 0x4B, 0x60, 0x19,
  0xE9, 0x58, 0xFF, 0xF7, 0xF9, 0xFE, 0x04, 0x35, 0xF3, 0xE7, 0x31, 0x68, 0x1A, 0x88, 0x92, 0xB2,
  0x0A, 0x44, 0x32, 0x60, 0x00, 0x22, 0x1A, 0x80, 0x70, 0xBD, 0x00, 0xBF, 0x5C, 0x0B, 0x00, 0x20,
  0x58, 0x0B, 0x00, 0x20, 0x56, 0x0B, 0x00, 0x20, 0x54, 0x03, 0x00, 0x20, 0x2D, 0xE9, 0xF0, 0x41,
  0x7F, 0x49, 0x80, 0x4C, 0x01, 0x20, 0x08, 0x70, 0x23, 0x79, 0x00, 0x22, 0xDB, 0xB2, 0x02, 0x2B,
  0x22, 0x70, 0x56, 0xD1, 0x08, 0x70, 0x7C, 0x49, 0x09, 0x68, 0x48, 0x78, 0x01, 0x28, 0x26, 0xD1,
  0xC8, 0x88, 0x00, 0x28, 0x00, 0xF0, 0xC1, 0x80, 0x78, 0x48, 0x09, 0x7B, 0x02, 0x60, 0x01, 0x29,
  0x4F, 0xF0, 0x03, 0x02, 0x22, 0x71, 0x0B, 0xD0, 0x02, 0x29, 0x16, 0xD1, 0x74, 0x4B, 0x1A, 0x70,
  0x74, 0x4A, 0x75, 0x4B, 0x1A, 0x60, 0xFF, 0xF7, 0x27, 0xFE, 0xFF, 0xF7, 0xE9, 0xFE, 0xCF, 0xE0,
  0x72, 0x49, 0x71, 0x4A, 0x11, 0x60, 0x6E, 0x4A, 0x13, 0x70, 0xFF, 0xF7, 0x1D, 0xFE, 0xFF, 0xF7,
  0xDF, 0xFE, 0x6C, 0x48, 0xFF, 0xF7, 0x96, 0xFE, 0xC2, 0xE0, 0x0A, 0x23, 0x62, 0xE0, 0x02, 0x28,
  0x21, 0xD1, 0x09, 0x23, 0x23, 0x71, 0xCA, 0x88, 0x69, 0x4B, 0x1A, 0x80, 0x18, 0x88, 0x69, 0x4A,
  0x80, 0xB2, 0x10, 0x80, 0x1A, 0x88, 0x4B, 0x88, 0x92, 0xB2, 0x5A, 0x43, 0x5F, 0x4B, 0x1A, 0x60,
  0x0B, 0x7B, 0x01, 0x2B, 0x03, 0xD0, 0x02, 0x2B, 0x09, 0xD1, 0x5E, 0x4A, 0x00, 0xE0, 0x5F, 0x4A,
  0x5D, 0x4B, 0x1A, 0x60, 0xFF, 0xF7, 0xD2, 0xFE, 0x5F, 0x4B, 0x18, 0x60, 0xA0, 0xE0, 0x0A, 0x23,
  0x23, 0x71, 0x03, 0x23, 0x9B, 0xE0, 0x06, 0x28, 0x3C, 0xD0, 0x03, 0x28, 0x19, 0xD0, 0x05, 0x28,
  0x3C, 0xE0, 0x03, 0x2B, 0x0B, 0xD1, 0x50, 0x4A, 0x12, 0x68, 0x52, 0x78, 0x03, 0x2A, 0x04, 0xD1,
  0x05, 0x23, 0x23, 0x71, 0xFF, 0xF7, 0x64, 0xFF, 0x8A, 0xE0, 0x05, 0x2A, 0x2E, 0xE0, 0x04, 0x2B,
  0x09, 0xD1, 0x52, 0x49, 0x08, 0x78, 0x02, 0x28, 0x03, 0xD1, 0x03, 0x23, 0x62, 0x70, 0x0B, 0x70,
  0x05, 0x23, 0x23, 0x71, 0x7C, 0xE0, 0x05, 0x2B, 0x14, 0xD1, 0x43, 0x4B, 0x1A, 0x68, 0x53, 0x78,
  0x01, 0x2B, 0x08, 0xD1, 0xD3, 0x88, 0x0B, 0xB1, 0x03, 0x23, 0xF2, 0xE7, 0x06, 0x23, 0x23, 0x71,
  0xFF, 0xF7, 0x80, 0xFE, 0x6C, 0xE0, 0x06, 0x2B, 0x4D, 0xD0, 0x03, 0x2B, 0x4B, 0xD0, 0x05, 0x2B,
  0x62, 0xD1, 0x48, 0xE0, 0x06, 0x2B, 0x0B, 0xD1, 0x37, 0x49, 0x09, 0x68, 0x49, 0x78, 0x03, 0x29,
  0x03, 0xD1, 0x08, 0x23, 0x23, 0x71, 0x22, 0x70, 0x5A, 0xE0, 0x05, 0x29, 0x54, 0xD1, 0xD8, 0xE7,
  0x07, 0x2B, 0xF6, 0xD0, 0x08, 0x2B, 0xD4, 0xD0, 0x09, 0x2B, 0x3C, 0xD1, 0x2E, 0x4B, 0x1A, 0x68,
  0x53, 0x78, 0x02, 0x2B, 0x2D, 0xD1, 0xD0, 0x88, 0x38, 0xB3, 0x31, 0x49, 0x52, 0x88, 0x0B, 0x88,
  0x2D, 0x4D, 0x9B, 0xB2, 0x53, 0x43, 0x29, 0x4A, 0x2F, 0x4E, 0x13, 0x60, 0x2F, 0x68, 0xD2, 0xF8,
  0x00, 0x80, 0xB1, 0xF8, 0x00, 0xC0, 0x47, 0x44, 0x33, 0x68, 0x1F, 0xFA, 0x8C, 0xFC, 0x67, 0x44,
  0x9F, 0x42, 0x28, 0x4B, 0x03, 0xD8, 0x0A, 0x88, 0x92, 0xB2, 0x1A, 0x80, 0x19, 0xE0, 0x36, 0x68,
  0x2D, 0x68, 0x11, 0x68, 0x72, 0x1B, 0x52, 0x1A, 0x92, 0xB2, 0x1A, 0x80, 0x1A, 0x88, 0x92, 0xB2,
  0x82, 0x42, 0x08, 0xD3, 0x00, 0x22, 0x1A, 0x80, 0x05, 0xE0, 0x0A, 0x23, 0x23, 0x71, 0x09, 0x23,
  0x1D, 0xE0, 0x06, 0x2B, 0x01, 0xD1, 0x02, 0x23, 0x9B, 0xE7, 0x03, 0x2B, 0x01, 0xD0, 0x05, 0x2B,
  0x12, 0xD1, 0x09, 0x23, 0x95, 0xE7, 0x0A, 0x2B, 0x0E, 0xD1, 0x0F, 0x4B, 0x1B, 0x68, 0x5B, 0x78,
  0x03, 0x2B, 0x01, 0xD1, 0x0A, 0x23, 0x8C, 0xE7, 0x05, 0x2B, 0xFB, 0xD0, 0x04, 0x2B, 0x03, 0xD1,
  0x02, 0x23, 0x23, 0x71, 0x00, 0x23, 0x02, 0xE0, 0x0A, 0x23, 0x23, 0x71, 0x0F, 0x23, 0x23, 0x70,
  0x20, 0x78, 0xD0, 0xF1, 0x01, 0x00, 0x38, 0xBF, 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0xBF,
  0x63, 0x0B, 0x00, 0x20, 0x5D, 0x0B, 0x00, 0x20, 0x44, 0x03, 0x00, 0x20, 0x58, 0x0B, 0x00, 0x20,
  0x5C, 0x0B, 0x00, 0x20, 0x00, 0x20, 0x00, 0x08, 0x04, 0x03, 0x00, 0x20, 0x00, 0x50, 0x00, 0x08,
  0x54, 0x0B, 0x00, 0x20, 0x56, 0x0B, 0x00, 0x20, 0x00, 0x03, 0x00, 0x20, 0x10, 0x03, 0x00, 0x20,
  0x01, 0x4B, 0x18, 0x78, 0x70, 0x47, 0x00, 0xBF, 0x63, 0x0B, 0x00, 0x20, 0x00, 0xBF, 0xFD, 0xE7,
  0x80, 0x00, 0x00, 0xF1, 0x80, 0x40, 0x00, 0xF5, 0xB8, 0x40, 0x03, 0x68, 0xCA, 0x06, 0x23, 0xF4,
  0xE0, 0x43, 0x23, 0xF0, 0x40, 0x03, 0x9B, 0xB2, 0x48, 0xBF, 0x83, 0xF0, 0x10, 0x03, 0x8A, 0x06,
  0x48, 0xBF, 0x83, 0xF0, 0x20, 0x03, 0x03, 0x60, 0x70, 0x47, 0x80, 0x00, 0x00, 0xF1, 0x80, 0x40,
  0x00, 0xF5, 0xB8, 0x40, 0x03, 0x68, 0x23, 0xF4, 0x80, 0x43, 0x23, 0xF0, 0x70, 0x03, 0x9B, 0xB2,
  0x83, 0xF4, 0x40, 0x53, 0x03, 0x60, 0x70, 0x47, 0x80, 0x00, 0x00, 0xF1, 0x80, 0x40, 0x00, 0xF5,
  0xB8, 0x40, 0x03, 0x68, 0x23, 0xF4, 0xE2, 0x43, 0x23, 0xF0, 0x70, 0x03, 0x1B, 0x04, 0x1B, 0x0C,
  0x03, 0x60, 0x70, 0x47, 0x80, 0x00, 0x00, 0xF1, 0x80, 0x40, 0x00, 0xF5, 0xB8, 0x40, 0x03, 0x68,
  0x5B, 0x04, 0x06, 0xD5, 0x02, 0x68, 0x48, 0xF6, 0x8F, 0x73, 0x13, 0x40, 0x43, 0xF4, 0x80, 0x43,
  0x03, 0x60, 0x70, 0x47, 0x80, 0x00, 0x00, 0xF1, 0x80, 0x40, 0x00, 0xF5, 0xB8, 0x40, 0x03, 0x68,
  0x5B, 0x06, 0x06, 0xD5, 0x02, 0x68, 0x48, 0xF6, 0x8F, 0x73, 0x13, 0x40, 0x43, 0xF0, 0x40, 0x03,
  0x03, 0x60, 0x70, 0x47, 0x05, 0x4B, 0x1B, 0x68, 0x9B, 0xB2, 0x03, 0xEB, 0xC0, 0x00, 0x00, 0xF1,
  0x00, 0x50, 0x00, 0xF5, 0x40, 0x50, 0x40, 0x00, 0x00, 0x88, 0x70, 0x47, 0x50, 0x5C, 0x00, 0x40,
  0x04, 0x4B, 0x1B, 0x68, 0x9B, 0xB2, 0x03, 0xEB, 0xC0, 0x00, 0x03, 0x4B, 0x03, 0x44, 0x5B, 0x00,
  0x18, 0x88, 0x70, 0x47, 0x50, 0x5C, 0x00, 0x40, 0x04, 0x30, 0x00, 0x20, 0x04, 0x4B, 0x1B, 0x68,
  0x9B, 0xB2, 0x03, 0xEB, 0xC0, 0x00, 0x03, 0x4B, 0x03, 0x44, 0x5B, 0x00, 0x19, 0x60, 0x70, 0x47,
  0x50, 0x5C, 0x00, 0x40, 0x02, 0x30, 0x00, 0x20, 0x0D, 0x4B, 0x3E, 0x29, 0x1B, 0x68, 0x9B, 0xB2,
  0x03, 0xEB, 0xC0, 0x00, 0x0B, 0x4B, 0x03, 0x44, 0x4F, 0xEA, 0x43, 0x02, 0x09, 0xD9, 0x4B, 0x09,
  0xC8, 0x06, 0x04, 0xBF, 0x03, 0xF1, 0xFF, 0x33, 0x9B, 0xB2, 0x9B, 0x02, 0x43, 0xF4, 0x00, 0x43,
  0x04, 0xE0, 0x4B, 0x08, 0xC9, 0x07, 0x48, 0xBF, 0x01, 0x33, 0x9B, 0x02, 0x13, 0x60, 0x70, 0x47,
  0x50, 0x5C, 0x00, 0x40, 0x06, 0x30, 0x00, 0x20, 0x70, 0xB5, 0x4C, 0x4A, 0x4C, 0x4B, 0x11, 0x68,
  0x88, 0xB2, 0x0C, 0x04, 0x18, 0x80, 0x40, 0xF1, 0x90, 0x80, 0x47, 0xF6, 0xFF, 0x71, 0x11, 0x60,
  0x1A, 0x88, 0x48, 0x4C, 0x02, 0xF0, 0x0F, 0x02, 0x22, 0x70, 0x00, 0x2A, 0x5F, 0xD1, 0x46, 0x4C,
  0x46, 0x4D, 0x22, 0x68, 0x46, 0x4E, 0x02, 0xF4, 0x40, 0x52, 0x2A, 0x80, 0x22, 0x68, 0x02, 0xF0,
  0x30, 0x02, 0x32, 0x80, 0x22, 0x68, 0x22, 0xF4, 0x80, 0x42, 0x22, 0xF0, 0x70, 0x02, 0x92, 0xB2,
  0x82, 0xF4, 0x00, 0x52, 0x22, 0x60, 0x22, 0x68, 0x22, 0xF4, 0xE0, 0x42, 0x22, 0xF0, 0x40, 0x02,
  0x92, 0xB2, 0x82, 0xF0, 0x20, 0x02, 0x22, 0x60, 0x1B, 0x88, 0xD8, 0x06, 0x02, 0xD5, 0x23, 0x68,
  0x19, 0x06, 0x07, 0xD5, 0x22, 0x68, 0x48, 0xF6, 0x0F, 0x73, 0x13, 0x40, 0x23, 0x60, 0x00, 0xF0,
  0x61, 0xFC, 0x12, 0xE0, 0x1A, 0x05, 0x07, 0xD5, 0x22, 0x68, 0x40, 0xF6, 0x8F, 0x73, 0x13, 0x40,
  0x23, 0x60, 0x00, 0xF0, 0x69, 0xFA, 0x08, 0xE0, 0x18, 0x04, 0xB6, 0xD5, 0x22, 0x68, 0x40, 0xF6,
  0x8F, 0x73, 0x13, 0x40, 0x23, 0x60, 0x00, 0xF0, 0xCD, 0xFB, 0x23, 0x68, 0x2A, 0x88, 0x23, 0xF4,
  0x80, 0x43, 0x23, 0xF0, 0x70, 0x03, 0x9B, 0xB2, 0xD1, 0x04, 0x48, 0xBF, 0x83, 0xF4, 0x80, 0x53,
  0x95, 0x04, 0x21, 0x4A, 0x48, 0xBF, 0x83, 0xF4, 0x00, 0x53, 0x13, 0x60, 0x13, 0x68, 0x31, 0x88,
  0x23, 0xF4, 0xE0, 0x43, 0x23, 0xF0, 0x40, 0x03, 0x9B, 0xB2, 0xCC, 0x06, 0x48, 0xBF, 0x83, 0xF0,
  0x10, 0x03, 0x88, 0x06, 0x48, 0xBF, 0x83, 0xF0, 0x20, 0x03, 0x13, 0x60, 0x70, 0xBD, 0x93, 0x00,
  0x03, 0xF1, 0x80, 0x43, 0x03, 0xF5, 0xB8, 0x43, 0x1D, 0x68, 0x29, 0x04, 0x09, 0xD5, 0x18, 0x68,
  0x40, 0xF6, 0x8F, 0x71, 0x01, 0x40, 0x19, 0x60, 0x12, 0x4B, 0x01, 0x3A, 0x53, 0xF8, 0x22, 0x30,
  0x98, 0x47, 0x2B, 0x06, 0x7F, 0xF5, 0x79, 0xAF, 0x21, 0x78, 0x48, 0xF6, 0x0F, 0x72, 0x8B, 0x00,
  0x03, 0xF1, 0x80, 0x43, 0x03, 0xF5, 0xB8, 0x43, 0x18, 0x68, 0x01, 0x39, 0x02, 0x40, 0x1A, 0x60,
  0x09, 0x4B, 0x53, 0xF8, 0x21, 0x30, 0x98, 0x47, 0x67, 0xE7, 0x70, 0xBD, 0x44, 0x5C, 0x00, 0x40,
  0x0C, 0x03, 0x00, 0x20, 0x20, 0x03, 0x00, 0x20, 0x00, 0x5C, 0x00, 0x40, 0x12, 0x03, 0x00, 0x20,
  0x14, 0x03, 0x00, 0x20, 0x50, 0x00, 0x00, 0x20, 0x34, 0x00, 0x00, 0x20, 0x08, 0xB5, 0x07, 0x4A,
  0x07, 0x4B, 0x08, 0x49, 0x13, 0x60, 0x02, 0x22, 0x1A, 0x72, 0x07, 0x4B, 0x07, 0x4A, 0x13, 0x60,
  0x07, 0x4A, 0x1B, 0x68, 0x11, 0x60, 0x98, 0x47, 0x08, 0xBD, 0x00, 0xBF, 0x44, 0x03, 0x00, 0x20,
  0x24, 0x03, 0x00, 0x20, 0x6C, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x1C, 0x03, 0x00, 0x20,
  0x40, 0x03, 0x00, 0x20, 0x10, 0xB5, 0x06, 0x4C, 0x18, 0xB9, 0x23, 0x68, 0x01, 0x22, 0x1A, 0x82,
  0x10, 0xBD, 0x04, 0x4B, 0x1B, 0x68, 0x1B, 0x68, 0x98, 0x47, 0x20, 0x68, 0x0A, 0x30, 0x10, 0xBD,
  0x44, 0x03, 0x00, 0x20, 0x40, 0x03, 0x00, 0x20, 0x10, 0xB5, 0x06, 0x4C, 0x18, 0xB9, 0x23, 0x68,
  0x01, 0x22, 0x1A, 0x82, 0x10, 0xBD, 0x04, 0x4B, 0x1B, 0x68, 0x9B, 0x68, 0x98, 0x47, 0x20, 0x68,
  0x0C, 0x30, 0x10, 0xBD, 0x44, 0x03, 0x00, 0x20, 0x40, 0x03, 0x00, 0x20, 0x10, 0xB5, 0x20, 0x4B,
  0x18, 0xB9, 0x1B, 0x68, 0x02, 0x22, 0x1A, 0x82, 0x10, 0xBD, 0x1E, 0x4A, 0x19, 0x68, 0x00, 0x20,
  0x10, 0x80, 0x0C, 0x78, 0x13, 0x46, 0x14, 0xF0, 0x7F, 0x04, 0x0D, 0xD1, 0x4A, 0x7A, 0x91, 0x06,
  0x44, 0xBF, 0x02, 0x21, 0x19, 0x70, 0x12, 0xF0, 0x40, 0x0F, 0x1A, 0x78, 0x14, 0xBF, 0x22, 0xF0,
  0x01, 0x02, 0x42, 0xF0, 0x01, 0x02, 0x14, 0xE0, 0x01, 0x2C, 0x1F, 0xD0, 0x02, 0x2C, 0x1E, 0xD1,
  0x09, 0x79, 0x01, 0xF0, 0x0F, 0x02, 0x92, 0x00, 0x02, 0xF1, 0x80, 0x42, 0x02, 0xF5, 0xB8, 0x42,
  0x11, 0xF0, 0x80, 0x0F, 0x12, 0x68, 0x06, 0xD0, 0x02, 0xF0, 0x30, 0x02, 0x10, 0x2A, 0x07, 0xD1,
  0x01, 0x22, 0x1A, 0x70, 0x04, 0xE0, 0x02, 0xF4, 0x40, 0x52, 0xB2, 0xF5, 0x80, 0x5F, 0xF6, 0xE7,
  0x05, 0x4B, 0x1B, 0x68, 0x1B, 0x69, 0x98, 0x47, 0x02, 0x48, 0x10, 0xBD, 0x10, 0x46, 0x10, 0xBD,
  0x44, 0x03, 0x00, 0x20, 0x4A, 0x03, 0x00, 0x20, 0x40, 0x03, 0x00, 0x20, 0x23, 0x4A, 0x2D, 0xE9,
  0xF8, 0x43, 0x14, 0x68, 0x90, 0x46, 0x23, 0x8A, 0x26, 0x7A, 0x21, 0x4F, 0xA3, 0xB9, 0x04, 0x2E,
  0x12, 0xD1, 0x20, 0x49, 0x0A, 0x78, 0x01, 0x2A, 0x0A, 0xD1, 0x1F, 0x4A, 0x10, 0x68, 0x1F, 0x4A,
  0x80, 0xB2, 0x02, 0x44, 0x52, 0x00, 0x13, 0x60, 0x30, 0x22, 0x3A, 0x80, 0x0B, 0x70, 0x27, 0xE0,
  0x10, 0x23, 0x3B, 0x80, 0x07, 0x26, 0x23, 0xE0, 0xA5, 0x8A, 0xAB, 0x42, 0x8C, 0xBF, 0x02, 0x26,
  0x04, 0x26, 0x9D, 0x42, 0x28, 0xBF, 0x1D, 0x46, 0x28, 0x46, 0xA3, 0x69, 0x98, 0x47, 0x81, 0x46,
  0x00, 0x20, 0xFF, 0xF7, 0x57, 0xFE, 0x2A, 0x46, 0x01, 0x46, 0x48, 0x46, 0x00, 0xF0, 0x68, 0xFB,
  0x29, 0x46, 0x00, 0x20, 0xFF, 0xF7, 0x6A, 0xFE, 0x23, 0x8A, 0x4F, 0xF4, 0x40, 0x52, 0x5B, 0x1B,
  0x23, 0x82, 0x63, 0x8A, 0x1D, 0x44, 0x30, 0x23, 0x3B, 0x80, 0x09, 0x4B, 0x65, 0x82, 0x1A, 0x80,
  0xD8, 0xF8, 0x00, 0x30, 0x1E, 0x72, 0xBD, 0xE8, 0xF8, 0x83, 0x00, 0xBF, 0x44, 0x03, 0x00, 0x20,
  0x14, 0x03, 0x00, 0x20, 0x64, 0x0B, 0x00, 0x20, 0x50, 0x5C, 0x00, 0x40, 0x02, 0x30, 0x00, 0x20,
  0x12, 0x03, 0x00, 0x20, 0x10, 0xB5, 0x0A, 0x4B, 0x0A, 0x49, 0x1B, 0x68, 0x49, 0x78, 0x9A, 0x78,
  0x91, 0x42, 0x0A, 0xD3, 0xD9, 0x78, 0x41, 0xB9, 0x9C, 0x88, 0x34, 0xB9, 0x9A, 0x72, 0x06, 0x4B,
  0x1B, 0x68, 0x5B, 0x68, 0x98, 0x47, 0x20, 0x46, 0x10, 0xBD, 0x02, 0x20, 0x10, 0xBD, 0x00, 0xBF,
  0x44, 0x03, 0x00, 0x20, 0x90, 0x00, 0x00, 0x20, 0x40, 0x03, 0x00, 0x20, 0x38, 0xB5, 0x0E, 0x4A,
  0x0E, 0x4C, 0x12, 0x68, 0x23, 0x68, 0x92, 0x69, 0x18, 0x79, 0x99, 0x78, 0x90, 0x47, 0x23, 0x68,
  0x9A, 0x7A, 0x7A, 0xB1, 0x70, 0xB9, 0x5A, 0x79, 0x62, 0xB9, 0xDD, 0x78, 0x55, 0xB9, 0x08, 0x4B,
  0x1B, 0x68, 0xDB, 0x68, 0x98, 0x47, 0x23, 0x68, 0x28, 0x46, 0x1A, 0x79, 0xDA, 0x72, 0x9A, 0x78,
  0x1A, 0x73, 0x38, 0xBD, 0x02, 0x20, 0x38, 0xBD, 0x1C, 0x03, 0x00, 0x20, 0x44, 0x03, 0x00, 0x20,
  0x40, 0x03, 0x00, 0x20, 0x38, 0xB5, 0x2F, 0x4B, 0x1B, 0x68, 0x18, 0x78, 0x10, 0xF0, 0x7F, 0x00,
  0x04, 0xD1, 0x5A, 0x7A, 0x22, 0xF0, 0x20, 0x02, 0x5A, 0x72, 0x38, 0xBD, 0x02, 0x28, 0x4E, 0xD1,
  0x5A, 0x88, 0x00, 0x2A, 0x4C, 0xD1, 0x5A, 0x79, 0x00, 0x2A, 0x49, 0xD1, 0x1A, 0x79, 0x26, 0x4D,
  0x22, 0xF0, 0x80, 0x00, 0x84, 0x00, 0x04, 0xF1, 0x80, 0x41, 0x01, 0xF5, 0xB8, 0x41, 0x09, 0x68,
  0x2D, 0x78, 0x12, 0xF0, 0x80, 0x0F, 0x14, 0xBF, 0x01, 0xF0, 0x30, 0x01, 0x01, 0xF4, 0x40, 0x51,
  0xA8, 0x42, 0x34, 0xD2, 0x00, 0x29, 0x32, 0xD0, 0x9B, 0x7A, 0x83, 0xB3, 0x04, 0xF1, 0x80, 0x44,
  0x04, 0xF5, 0xB8, 0x44, 0x12, 0x06, 0x23, 0x68, 0x0C, 0xD5, 0x03, 0xF0, 0x30, 0x03, 0x10, 0x2B,
  0x1F, 0xD1, 0xC4, 0xB2, 0x20, 0x46, 0xFF, 0xF7, 0xA5, 0xFD, 0x20, 0x46, 0x30, 0x21, 0xFF, 0xF7,
  0x5F, 0xFD, 0x16, 0xE0, 0x03, 0xF4, 0x40, 0x53, 0xB3, 0xF5, 0x80, 0x5F, 0x11, 0xD1, 0x28, 0xB9,
  0x0E, 0x4B, 0x93, 0xF8, 0x30, 0x10, 0xFF, 0xF7, 0xCF, 0xFD, 0x01, 0xE0, 0xFF, 0xF7, 0x82, 0xFD,
  0x23, 0x68, 0x23, 0xF4, 0x80, 0x43, 0x23, 0xF0, 0x70, 0x03, 0x9B, 0xB2, 0x83, 0xF4, 0x40, 0x53,
  0x23, 0x60, 0x07, 0x4B, 0x1B, 0x68, 0x5B, 0x69, 0x98, 0x47, 0x00, 0x20, 0x38, 0xBD, 0x02, 0x20,
  0x38, 0xBD, 0x00, 0xBF, 0x44, 0x03, 0x00, 0x20, 0x90, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20,
  0x40, 0x03, 0x00, 0x20, 0x38, 0xB5, 0x1D, 0x4B, 0x1D, 0x4D, 0x19, 0x68, 0x2D, 0x78, 0x0A, 0x79,
  0x22, 0xF0, 0x80, 0x04, 0xA3, 0x00, 0x03, 0xF1, 0x80, 0x40, 0x00, 0xF5, 0xB8, 0x40, 0x00, 0x68,
  0x12, 0xF0, 0x80, 0x0F, 0x14, 0xBF, 0x00, 0xF0, 0x30, 0x00, 0x00, 0xF4, 0x40, 0x50, 0xAC, 0x42,
  0x22, 0xD2, 0x4C, 0x88, 0x04, 0xBB, 0xF8, 0xB1, 0x89, 0x7A, 0xE9, 0xB1, 0x03, 0xF1, 0x80, 0x43,
  0x03, 0xF5, 0xB8, 0x43, 0x12, 0xF0, 0x80, 0x0F, 0x1A, 0x68, 0x07, 0xD0, 0x22, 0xF4, 0xE0, 0x42,
  0x22, 0xF0, 0x40, 0x02, 0x92, 0xB2, 0x82, 0xF0, 0x10, 0x02, 0x06, 0xE0, 0x22, 0xF4, 0x80, 0x42,
  0x22, 0xF0, 0x70, 0x02, 0x92, 0xB2, 0x82, 0xF4, 0x80, 0x52, 0x1A, 0x60, 0x05, 0x4B, 0x1B, 0x68,
  0x9B, 0x69, 0x98, 0x47, 0x00, 0x20, 0x38, 0xBD, 0x02, 0x20, 0x38, 0xBD, 0x44, 0x03, 0x00, 0x20,
  0x90, 0x00, 0x00, 0x20, 0x40, 0x03, 0x00, 0x20, 0x08, 0xB5, 0x06, 0x4B, 0x1B, 0x68, 0x5A, 0x7A,
  0x42, 0xF0, 0x20, 0x02, 0x5A, 0x72, 0x04, 0x4B, 0x1B, 0x68, 0xDB, 0x69, 0x98, 0x47, 0x00, 0x20,
  0x08, 0xBD, 0x00, 0xBF, 0x44, 0x03, 0x00, 0x20, 0x40, 0x03, 0x00, 0x20, 0x05, 0x4B, 0x1A, 0x68,
  0x53, 0x8A, 0x18, 0xB9, 0x89, 0x88, 0xCB, 0x1A, 0x13, 0x82, 0x70, 0x47, 0x08, 0x68, 0x18, 0x44,
  0x70, 0x47, 0x00, 0xBF, 0x44, 0x03, 0x00, 0x20, 0x08, 0xB5, 0x0B, 0x4B, 0x00, 0x20, 0x93, 0xF8,
  0x30, 0x10, 0xFF, 0xF7, 0x49, 0xFD, 0x09, 0x4B, 0x1B, 0x68, 0x18, 0x7A, 0x08, 0x28, 0x06, 0xD1,
  0x07, 0x4B, 0x4F, 0xF4, 0x80, 0x52, 0x1A, 0x80, 0x06, 0x4B, 0x10, 0x22, 0x1A, 0x80, 0xB0, 0xF1,
  0x09, 0x03, 0x58, 0x42, 0x58, 0x41, 0x08, 0xBD, 0x00, 0x00, 0x00, 0x20, 0x44, 0x03, 0x00, 0x20,
  0x12, 0x03, 0x00, 0x20, 0x14, 0x03, 0x00, 0x20, 0x73, 0xB5, 0x96, 0x4E, 0x96, 0x4B, 0x32, 0x68,
  0x96, 0x4D, 0x92, 0xB2, 0x13, 0x44, 0x5B, 0x00, 0x1A, 0x68, 0x2B, 0x68, 0x19, 0x7A, 0x09, 0x29,
  0x0F, 0xD0, 0x92, 0xB2, 0x52, 0x00, 0x02, 0xF1, 0x80, 0x42, 0x02, 0xF5, 0xC0, 0x42, 0x11, 0x78,
  0x19, 0x70, 0x51, 0x78, 0x59, 0x70, 0x91, 0x88, 0x59, 0x80, 0x11, 0x89, 0x99, 0x80, 0x92, 0x89,
  0xDA, 0x80, 0x01, 0x22, 0x1A, 0x72, 0xDA, 0x88, 0x5C, 0x78, 0x00, 0x2A, 0x61, 0xD1, 0x1A, 0x78,
  0x12, 0xF0, 0x7F, 0x02, 0x3A, 0xD1, 0x09, 0x2C, 0x02, 0xD1, 0xFF, 0xF7, 0xAB, 0xFE, 0x44, 0xE0,
  0x05, 0x2C, 0x0F, 0xD1, 0x93, 0xF9, 0x02, 0x20, 0x00, 0x2A, 0x01, 0xDA, 0x08, 0x23, 0x4D, 0xE0,
  0xDA, 0x78, 0x00, 0x2A, 0xFA, 0xD1, 0x9A, 0x88, 0x00, 0x2A, 0xF7, 0xD1, 0x9B, 0x7A, 0x00, 0x2B,
  0x37, 0xD0, 0xF3, 0xE7, 0x03, 0x2C, 0x13, 0xD1, 0x9A, 0x78, 0x01, 0x2A, 0x07, 0xD0, 0x78, 0x4B,
  0x20, 0x46, 0x1B, 0x68, 0x5B, 0x69, 0x98, 0x47, 0x03, 0x28, 0x28, 0xD1, 0x35, 0xE0, 0x9A, 0x88,
  0x00, 0x2A, 0xF4, 0xD1, 0x5B, 0x7A, 0x98, 0x06, 0xF1, 0xD5, 0xFF, 0xF7, 0x6D, 0xFF, 0x1C, 0xE0,
  0x01, 0x2C, 0xEC, 0xD1, 0x9A, 0x78, 0x01, 0x2A, 0xE9, 0xD1, 0x9A, 0x88, 0x00, 0x2A, 0xE6, 0xD1,
  0x5B, 0x7A, 0x99, 0x06, 0xE3, 0xD5, 0xFF, 0xF7, 0xB5, 0xFE, 0x0E, 0xE0, 0x01, 0x2A, 0x04, 0xD1,
  0x0B, 0x2C, 0xDC, 0xD1, 0xFF, 0xF7, 0x8A, 0xFE, 0x07, 0xE0, 0x02, 0x2A, 0xD7, 0xD1, 0x01, 0x2C,
  0xF1, 0xD0, 0x03, 0x2C, 0xD3, 0xD1, 0xFF, 0xF7, 0x0D, 0xFF, 0x10, 0xB1, 0xCF, 0xE7, 0x00, 0x28,
  0xBC, 0xD1, 0x32, 0x68, 0x5F, 0x4B, 0x92, 0xB2, 0x13, 0x44, 0x5B, 0x00, 0x00, 0x22, 0x1A, 0x60,
  0x5D, 0x4B, 0x30, 0x22, 0x1A, 0x80, 0x06, 0x23, 0x00, 0xE0, 0x09, 0x23, 0x2A, 0x68, 0x13, 0x72,
  0xD4, 0xE0, 0x06, 0x2C, 0x18, 0xD1, 0x1A, 0x78, 0x52, 0x06, 0x7C, 0xD1, 0xDA, 0x78, 0x54, 0x4B,
  0x01, 0x2A, 0x02, 0xD1, 0x1B, 0x68, 0xDB, 0x69, 0x6C, 0xE0, 0x02, 0x2A, 0x02, 0xD1, 0x1B, 0x68,
  0x1B, 0x6A, 0x67, 0xE0, 0x03, 0x2A, 0x02, 0xD1, 0x1B, 0x68, 0x5B, 0x6A, 0x62, 0xE0, 0x21, 0x2A,
  0x69, 0xD1, 0x1B, 0x68, 0x9B, 0x6A, 0x5D, 0xE0, 0x00, 0x2C, 0x3C, 0xD1, 0x59, 0x88, 0x00, 0x29,
  0x61, 0xD1, 0x5A, 0x68, 0x22, 0xF0, 0xFF, 0x02, 0xB2, 0xF5, 0x00, 0x3F, 0x5B, 0xD1, 0x1A, 0x78,
  0x12, 0xF0, 0x7F, 0x02, 0x04, 0xD1, 0x9B, 0x88, 0x00, 0x2B, 0x00, 0xF0, 0xAB, 0x80, 0x52, 0xE0,
  0x01, 0x2A, 0x0C, 0xD1, 0x3E, 0x4A, 0x18, 0x79, 0x12, 0x68, 0x92, 0x69, 0x90, 0x47, 0x00, 0x28,
  0x49, 0xD1, 0x2B, 0x68, 0x9B, 0x7A, 0x00, 0x2B, 0x40, 0xF0, 0x9C, 0x80, 0x43, 0xE0, 0x02, 0x2A,
  0x41, 0xD1, 0x1B, 0x79, 0x39, 0x48, 0x03, 0xF0, 0x0F, 0x01, 0x8A, 0x00, 0x02, 0xF1, 0x80, 0x42,
  0x02, 0xF5, 0xB8, 0x42, 0x12, 0x68, 0x00, 0x78, 0x13, 0xF0, 0x80, 0x0F, 0x14, 0xBF, 0x02, 0xF0,
  0x30, 0x02, 0x02, 0xF4, 0x40, 0x52, 0x81, 0x42, 0x2D, 0xD2, 0x13, 0xF0, 0x70, 0x0F, 0x2A, 0xD1,
  0x00, 0x2A, 0x7F, 0xD1, 0x27, 0xE0, 0x08, 0x2C, 0x03, 0xD1, 0x1B, 0x78, 0x5B, 0x06, 0x7B, 0xD0,
  0x21, 0xE0, 0x0A, 0x2C, 0x1F, 0xD1, 0x1A, 0x78, 0x02, 0xF0, 0x7F, 0x02, 0x01, 0x2A, 0x1A, 0xD1,
  0x9A, 0x7A, 0xC2, 0xB1, 0x59, 0x88, 0xB1, 0xB9, 0x5A, 0x68, 0x22, 0xF0, 0xFF, 0x02, 0xB2, 0xF5,
  0x80, 0x3F, 0x10, 0xD1, 0x1E, 0x4A, 0x18, 0x79, 0x12, 0x68, 0x92, 0x69, 0x90, 0x47, 0x00, 0x28,
  0x64, 0xD0, 0x08, 0xE0, 0x3B, 0xB1, 0x2A, 0x68, 0x00, 0x24, 0x54, 0x82, 0x93, 0x61, 0x20, 0x46,
  0x98, 0x47, 0x20, 0x46, 0x0A, 0xE0, 0x16, 0x4B, 0x1A, 0x68, 0x2B, 0x68, 0x12, 0x69, 0x58, 0x78,
  0x90, 0x47, 0x03, 0x28, 0x02, 0xD1, 0x11, 0x4B, 0x1B, 0x68, 0x05, 0xE0, 0x2B, 0x68, 0x4F, 0xF6,
  0xFF, 0x71, 0x1A, 0x8A, 0x8A, 0x42, 0x01, 0xD1, 0x09, 0x22, 0x03, 0xE0, 0x02, 0x28, 0x00, 0xD0,
  0x12, 0xB9, 0x08, 0x22, 0x1A, 0x72, 0x39, 0xE0, 0x93, 0xF9, 0x00, 0x10, 0x00, 0x29, 0x2F, 0xDA,
  0xD9, 0x88, 0x01, 0x91, 0x01, 0x98, 0x82, 0x42, 0x05, 0x48, 0x11, 0xD9, 0x01, 0x9A, 0x1A, 0x82,
  0x1F, 0xE0, 0x00, 0xBF, 0x50, 0x5C, 0x00, 0x40, 0x04, 0x30, 0x00, 0x20, 0x44, 0x03, 0x00, 0x20,
  0x1C, 0x03, 0x00, 0x20, 0x02, 0x30, 0x00, 0x20, 0x14, 0x03, 0x00, 0x20, 0x90, 0x00, 0x00, 0x20,
  0x8A, 0x42, 0x0E, 0xD2, 0x01, 0x68, 0x91, 0xF8, 0x30, 0x10, 0x8A, 0x42, 0x01, 0xD2, 0x00, 0x21,
  0x05, 0xE0, 0x92, 0xFB, 0xF1, 0xF4, 0x01, 0xFB, 0x14, 0x22, 0x12, 0xB9, 0x01, 0x21, 0x0C, 0x4A,
  0x11, 0x70, 0x02, 0x68, 0x92, 0xF8, 0x30, 0x20, 0x9A, 0x82, 0xFF, 0xF7, 0x2F, 0xFD, 0x05, 0xE0,
  0x03, 0x22, 0x1A, 0x72, 0x07, 0x4B, 0x4F, 0xF4, 0x40, 0x52, 0x1A, 0x80, 0xFF, 0xF7, 0x84, 0xFE,
  0x02, 0xB0, 0x70, 0xBD, 0x04, 0x4B, 0x9E, 0xE7, 0x04, 0x4B, 0x9C, 0xE7, 0x04, 0x4B, 0x9A, 0xE7,
  0x64, 0x0B, 0x00, 0x20, 0x12, 0x03, 0x00, 0x20, 0x9D, 0x10, 0x00, 0x08, 0x55, 0x10, 0x00, 0x08,
  0x79, 0x10, 0x00, 0x08, 0xF8, 0xB5, 0x2B, 0x4D, 0x2C, 0x68, 0x23, 0x7A, 0x03, 0x2B, 0x01, 0xD0,
  0x05, 0x2B, 0x41, 0xD1, 0xA3, 0x69, 0x22, 0x8A, 0xAB, 0xB1, 0xA2, 0xB1, 0xA6, 0x8A, 0x96, 0x42,
  0x28, 0xBF, 0x16, 0x46, 0x30, 0x46, 0x98, 0x47, 0x23, 0x8A, 0x07, 0x46, 0x9B, 0x1B, 0x23, 0x82,
  0x63, 0x8A, 0x00, 0x20, 0x33, 0x44, 0x63, 0x82, 0xFF, 0xF7, 0x8A, 0xFB, 0x32, 0x46, 0x01, 0x46,
  0x38, 0x46, 0x00, 0xF0, 0xA5, 0xF8, 0x23, 0x8A, 0x53, 0xB1, 0x1B, 0x4B, 0x00, 0x20, 0x4F, 0xF4,
  0x40, 0x52, 0x01, 0x46, 0x1A, 0x80, 0xFF, 0xF7, 0x89, 0xFB, 0x18, 0x4B, 0x30, 0x22, 0x1A, 0x80,
  0x23, 0x8A, 0xA2, 0x8A, 0x9A, 0x42, 0x02, 0xD8, 0x2B, 0x68, 0x03, 0x22, 0x02, 0xE0, 0x1B, 0xB1,
  0x2B, 0x68, 0x05, 0x22, 0x1A, 0x72, 0x0C, 0xE0, 0x2A, 0x68, 0x06, 0x21, 0x11, 0x72, 0x10, 0x4A,
  0x11, 0x68, 0x10, 0x4A, 0x89, 0xB2, 0x0A, 0x44, 0x52, 0x00, 0x13, 0x60, 0x0B, 0x4B, 0x30, 0x22,
  0x1A, 0x80, 0x2B, 0x68, 0x1B, 0x7A, 0x06, 0xE0, 0x07, 0x2B, 0x03, 0xD1, 0x0A, 0x4B, 0x1B, 0x68,
  0xDB, 0x68, 0x98, 0x47, 0x08, 0x23, 0x2A, 0x68, 0x13, 0x72, 0xBD, 0xE8, 0xF8, 0x40, 0xFF, 0xF7,
  0x1B, 0xBE, 0x00, 0xBF, 0x44, 0x03, 0x00, 0x20, 0x12, 0x03, 0x00, 0x20, 0x14, 0x03, 0x00, 0x20,
  0x50, 0x5C, 0x00, 0x40, 0x02, 0x30, 0x00, 0x20, 0x1C, 0x03, 0x00, 0x20, 0x30, 0xB5, 0x0B, 0x4B,
  0x1C, 0x78, 0x00, 0x23, 0xA3, 0x42, 0x0C, 0xD2, 0x03, 0xF1, 0x80, 0x52, 0x02, 0xF5, 0xB8, 0x52,
  0x91, 0x00, 0x0D, 0x68, 0x48, 0xF6, 0x8F, 0x72, 0x2A, 0x40, 0x1A, 0x43, 0x0A, 0x60, 0x01, 0x33,
  0xF0, 0xE7, 0x03, 0x4B, 0x40, 0xF0, 0x80, 0x00, 0x18, 0x60, 0x30, 0xBD, 0x90, 0x00, 0x00, 0x20,
  0x4C, 0x5C, 0x00, 0x40, 0x10, 0xB5, 0x13, 0x4C, 0x23, 0x68, 0x1A, 0x7A, 0x02, 0x2A, 0x01, 0xD0,
  0x04, 0x2A, 0x04, 0xD1, 0xFF, 0xF7, 0x8A, 0xFC, 0x23, 0x68, 0x1B, 0x7A, 0x13, 0xE0, 0x06, 0x2A,
  0x10, 0xD1, 0x5A, 0x78, 0x05, 0x2A, 0x09, 0xD1, 0x1A, 0x78, 0x52, 0x06, 0x06, 0xD1, 0x98, 0x78,
  0xFF, 0xF7, 0xCC, 0xFF, 0x08, 0x4B, 0x1B, 0x68, 0x1B, 0x6A, 0x98, 0x47, 0x07, 0x4B, 0x1B, 0x68,
  0x9B, 0x68, 0x98, 0x47, 0x08, 0x23, 0x22, 0x68, 0x13, 0x72, 0xBD, 0xE8, 0x10, 0x40, 0xFF, 0xF7,
  0xCB, 0xBD, 0x00, 0xBF, 0x44, 0x03, 0x00, 0x20, 0x40, 0x03, 0x00, 0x20, 0x1C, 0x03, 0x00, 0x20,
  0x30, 0xB5, 0x01, 0xF1, 0x00, 0x51, 0x01, 0x32, 0x01, 0xF5, 0x40, 0x51, 0x52, 0x10, 0x49, 0x00,
  0x00, 0x23, 0x93, 0x42, 0x00, 0xF1, 0x02, 0x00, 0x09, 0xD0, 0x10, 0xF8, 0x01, 0x5C, 0x10, 0xF8,
  0x02, 0x4C, 0x44, 0xEA, 0x05, 0x24, 0x21, 0xF8, 0x23, 0x40, 0x01, 0x33, 0xF1, 0xE7, 0x30, 0xBD,
  0x10, 0xB5, 0x01, 0xF1, 0x00, 0x51, 0x01, 0x32, 0x01, 0xF5, 0x40, 0x51, 0x52, 0x10, 0x49, 0x00,
  0x00, 0x23, 0x93, 0x42, 0x05, 0xD0, 0x51, 0xF8, 0x23, 0x40, 0x20, 0xF8, 0x13, 0x40, 0x01, 0x33,
  0xF7, 0xE7, 0x10, 0xBD, 0xD5, 0x04, 0x00, 0x08, 0xFD, 0x01, 0x00, 0x08, 0xBB, 0x01, 0x00, 0x08,
  0xBD, 0x01, 0x00, 0x08, 0xA5, 0x02, 0x00, 0x08, 0x49, 0x03, 0x00, 0x08, 0xBF, 0x01, 0x00, 0x08,
  0x05, 0x03, 0x00, 0x08, 0x11, 0x03, 0x00, 0x08, 0x1D, 0x03, 0x00, 0x08, 0x3D, 0x03, 0x00, 0x08,
  0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0xB9, 0x01, 0x00, 0x08, 0xB9, 0x01, 0x00, 0x08,
  0xB9, 0x01, 0x00, 0x08, 0xB9, 0x01, 0x00, 0x08, 0xB9, 0x01, 0x00, 0x08, 0xB9, 0x01, 0x00, 0x08,
  0xB9, 0x01, 0x00, 0x08, 0xB9, 0x01, 0x00, 0x08, 0xB9, 0x01, 0x00, 0x08, 0xB9, 0x01, 0x00, 0x08,
  0xB9, 0x01, 0x00, 0x08, 0xB9, 0x01, 0x00, 0x08, 0xB9, 0x01, 0x00, 0x08, 0xB9, 0x01, 0x00, 0x08,
  0xC9, 0x01, 0x00, 0x08, 0xCD, 0x01, 0x00, 0x08, 0xE5, 0x01, 0x00, 0x08, 0xE7, 0x01, 0x00, 0x08,
  0xE9, 0x01, 0x00, 0x08, 0xEB, 0x01, 0x00, 0x08, 0xED, 0x01, 0x00, 0x08, 0xEF, 0x01, 0x00, 0x08,
  0xF1, 0x01, 0x00, 0x08, 0x01, 0x01, 0x00, 0x00, 0xE8, 0x00, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00,
  0x32, 0x01, 0x00, 0x20, 0x12, 0x00, 0x00, 0x00, 0x4C, 0x01, 0x00, 0x20, 0x14, 0x00, 0x00, 0x00,
  0x19, 0x01, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x60, 0x01, 0x00, 0x20, 0x8E, 0x00, 0x00, 0x00,
  0xEE, 0x01, 0x00, 0x20, 0x84, 0x00, 0x00, 0x00, 0x72, 0x02, 0x00, 0x20, 0x84, 0x00, 0x00, 0x00,
  0x12, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0xAF, 0x1E, 0x03, 0x00, 0x01, 0x02, 0x01, 0x02,
  0x03, 0x01, 0x00, 0x00, 0x29, 0x01, 0x00, 0x20, 0x09, 0x00, 0x00, 0x00, 0x04, 0x03, 0x09, 0x04,
  0x09, 0x02, 0x2D, 0x00, 0x01, 0x01, 0x00, 0x80, 0x32, 0x09, 0x04, 0x00, 0x00, 0x00, 0xFE, 0x01,
  0x02, 0x04, 0x09, 0x04, 0x00, 0x01, 0x00, 0xFE, 0x01, 0x02, 0x05, 0x09, 0x04, 0x00, 0x02, 0x00,
  0xFE, 0x01, 0x02, 0x06, 0x09, 0x21, 0x03, 0xFF, 0x00, 0x00, 0x08, 0x10, 0x01, 0x10, 0x03, 0x4C,
  0x00, 0x4C, 0x00, 0x4D, 0x00, 0x20, 0x00, 0x30, 0x00, 0x30, 0x00, 0x33, 0x00, 0x09, 0x21, 0x03,
  0xFF, 0x00, 0x00, 0x08, 0x10, 0x01, 0x12, 0x03, 0x4C, 0x00, 0x65, 0x00, 0x61, 0x00, 0x66, 0x00,
  0x4C, 0x00, 0x61, 0x00, 0x62, 0x00, 0x73, 0x00, 0xCC, 0x00, 0x00, 0x20, 0x12, 0x00, 0x00, 0x00,
  0x14, 0x03, 0x4D, 0x00, 0x61, 0x00, 0x70, 0x00, 0x6C, 0x00, 0x65, 0x00, 0x20, 0x00, 0x30, 0x00,
  0x30, 0x00, 0x33, 0x00, 0x8E, 0x03, 0x42, 0x00, 0x6F, 0x00, 0x6F, 0x00, 0x74, 0x00, 0x6C, 0x00,
  0x6F, 0x00, 0x61, 0x00, 0x64, 0x00, 0x65, 0x00, 0x72, 0x00, 0x20, 0x00, 0x32, 0x00, 0x2E, 0x00,
  0x30, 0x00, 0x2E, 0x00, 0x72, 0x00, 0x63, 0x00, 0x31, 0x00, 0x20, 0x00, 0x45, 0x00, 0x52, 0x00,
  0x52, 0x00, 0x4F, 0x00, 0x52, 0x00, 0x2E, 0x00, 0x20, 0x00, 0x55, 0x00, 0x70, 0x00, 0x6C, 0x00,
  0x6F, 0x00, 0x61, 0x00, 0x64, 0x00, 0x20, 0x00, 0x74, 0x00, 0x6F, 0x00, 0x20, 0x00, 0x52, 0x00,
  0x41, 0x00, 0x4D, 0x00, 0x20, 0x00, 0x69, 0x00, 0x73, 0x00, 0x20, 0x00, 0x6E, 0x00, 0x6F, 0x00,
  0x74, 0x00, 0x20, 0x00, 0x73, 0x00, 0x75, 0x00, 0x70, 0x00, 0x70, 0x00, 0x6F, 0x00, 0x72, 0x00,
  0x74, 0x00, 0x65, 0x00, 0x64, 0x00, 0x2E, 0x00, 0x20, 0x00, 0x28, 0x00, 0x4D, 0x00, 0x61, 0x00,
  0x70, 0x00, 0x6C, 0x00, 0x65, 0x00, 0x2D, 0x00, 0x6D, 0x00, 0x69, 0x00, 0x6E, 0x00, 0x69, 0x00,
  0x29, 0x00, 0x84, 0x03, 0x42, 0x00, 0x6F, 0x00, 0x6F, 0x00, 0x74, 0x00, 0x6C, 0x00, 0x6F, 0x00,
  0x61, 0x00, 0x64, 0x00, 0x65, 0x00, 0x72, 0x00, 0x20, 0x00, 0x32, 0x00, 0x2E, 0x00, 0x30, 0x00,
  0x2E, 0x00, 0x72, 0x00, 0x63, 0x00, 0x31, 0x00, 0x20, 0x00, 0x55, 0x00, 0x70, 0x00, 0x6C, 0x00,
  0x6F, 0x00, 0x61, 0x00, 0x64, 0x00, 0x20, 0x00, 0x74, 0x00, 0x6F, 0x00, 0x20, 0x00, 0x46, 0x00,
  0x6C, 0x00, 0x61, 0x00, 0x73, 0x00, 0x68, 0x00, 0x20, 0x00, 0x61, 0x00, 0x64, 0x00, 0x64, 0x00,
  0x72, 0x00, 0x65, 0x00, 0x73, 0x00, 0x73, 0x00, 0x20, 0x00, 0x30, 0x00, 0x78, 0x00, 0x38, 0x00,
  0x30, 0x00, 0x30, 0x00, 0x35, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x20, 0x00, 0x28, 0x00,
  0x4D, 0x00, 0x61, 0x00, 0x70, 0x00, 0x6C, 0x00, 0x65, 0x00, 0x2D, 0x00, 0x6D, 0x00, 0x69, 0x00,
  0x6E, 0x00, 0x69, 0x00, 0x29, 0x00, 0x84, 0x03, 0x42, 0x00, 0x6F, 0x00, 0x6F, 0x00, 0x74, 0x00,
  0x6C, 0x00, 0x6F, 0x00, 0x61, 0x00, 0x64, 0x00, 0x65, 0x00, 0x72, 0x00, 0x20, 0x00, 0x32, 0x00,
  0x2E, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x72, 0x00, 0x63, 0x00, 0x31, 0x00, 0x20, 0x00, 0x55, 0x00,
  0x70, 0x00, 0x6C, 0x00, 0x6F, 0x00, 0x61, 0x00, 0x64, 0x00, 0x20, 0x00, 0x74, 0x00, 0x6F, 0x00,
  0x20, 0x00, 0x46, 0x00, 0x6C, 0x00, 0x61, 0x00, 0x73, 0x00, 0x68, 0x00, 0x20, 0x00, 0x61, 0x00,
  0x64, 0x00, 0x64, 0x00, 0x72, 0x00, 0x65, 0x00, 0x73, 0x00, 0x73, 0x00, 0x20, 0x00, 0x30, 0x00,
  0x78, 0x00, 0x38, 0x00, 0x30, 0x00, 0x30, 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00,
  0x20, 0x00, 0x28, 0x00, 0x4D, 0x00, 0x61, 0x00, 0x70, 0x00, 0x6C, 0x00, 0x65, 0x00, 0x2D, 0x00,
  0x6D, 0x00, 0x69, 0x00, 0x6E, 0x00, 0x69, 0x00, 0x29, 0x00, 0x00, 0x00, 0xEC, 0x00, 0x00, 0x20,
  0x2D, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x20, 0x00, 0x0C, 0x00, 0x20
};

#define BOARD_LED_PIN 33


typedef struct {
  volatile uint32 CR;
  volatile uint32 CFGR;
  volatile uint32 CIR;
  volatile uint32 APB2RSTR;
  volatile uint32 APB1RSTR;
  volatile uint32 AHBENR;
  volatile uint32 APB2ENR;
  volatile uint32 APB1ENR;
  volatile uint32 BDCR;
  volatile uint32 CSR;
} RCC_RegStruct;

typedef enum { RESET = 0, SET   = !RESET } FlagStatus, ITStatus;

typedef enum { DISABLE = 0, ENABLE  = !DISABLE} FunctionalState;

typedef enum { ERROR = 0, SUCCESS  = !ERROR} ErrorStatus;

#define BOOTLOADER_FLASH   ((uint32)0x08000000)
#define PAGE_SIZE          1024

#define SET_REG(addr,val) do { *(volatile uint32*)(addr)=val; } while(0)
#define GET_REG(addr)     (*(volatile uint32*)(addr))


#define RCC   ((uint32)0x40021000)
#define FLASH ((uint32)0x40022000)

#define RCC_CR      RCC
#define RCC_CFGR    (RCC + 0x04)
#define RCC_CIR     (RCC + 0x08)
#define RCC_AHBENR  (RCC + 0x14)
#define RCC_APB2ENR (RCC + 0x18)
#define RCC_APB1ENR (RCC + 0x1C)

#define FLASH_ACR     (FLASH + 0x00)
#define FLASH_KEYR    (FLASH + 0x04)
#define FLASH_OPTKEYR (FLASH + 0x08)
#define FLASH_SR      (FLASH + 0x0C)
#define FLASH_CR      (FLASH + 0x10)
#define FLASH_AR      (FLASH + 0x14)
#define FLASH_OBR     (FLASH + 0x1C)
#define FLASH_WRPR    (FLASH + 0x20)

#define FLASH_KEY1     0x45670123
#define FLASH_KEY2     0xCDEF89AB
#define FLASH_RDPRT    0x00A5
#define FLASH_SR_BSY   0x01
#define FLASH_CR_PER   0x02
#define FLASH_CR_PG    0x01
#define FLASH_CR_START 0x40

#define pRCC ((RCC_RegStruct *) RCC)



bool flashErasePage(uint32 pageAddr) {
  uint32 rwmVal = GET_REG(FLASH_CR);
  rwmVal = FLASH_CR_PER;
  SET_REG(FLASH_CR, rwmVal);

  while (GET_REG(FLASH_SR) & FLASH_SR_BSY) {}
  SET_REG(FLASH_AR, pageAddr);
  SET_REG(FLASH_CR, FLASH_CR_START | FLASH_CR_PER);
  while (GET_REG(FLASH_SR) & FLASH_SR_BSY) {}

  /* todo: verify the page was erased */

  rwmVal = 0x00;
  SET_REG(FLASH_CR, rwmVal);

  return true;
}
bool flashErasePages(uint32 pageAddr, uint16 n) {
  while (n-- > 0) {
    if (!flashErasePage(pageAddr + 0x400 * n)) {
      return false;
    }
  }

  return true;
}

bool flashWriteWord(uint32 addr, uint32 word) {
  volatile uint16 *flashAddr = (volatile uint16 *)addr;
  volatile uint32 lhWord = (volatile uint32)word & 0x0000FFFF;
  volatile uint32 hhWord = ((volatile uint32)word & 0xFFFF0000) >> 16;

  uint32 rwmVal = GET_REG(FLASH_CR);
  SET_REG(FLASH_CR, FLASH_CR_PG);

  /* apparently we need not write to FLASH_AR and can
     simply do a native write of a half word */
  while (GET_REG(FLASH_SR) & FLASH_SR_BSY) {}
  *(flashAddr + 0x01) = (volatile uint16)hhWord;
  while (GET_REG(FLASH_SR) & FLASH_SR_BSY) {}
  *(flashAddr) = (volatile uint16)lhWord;
  while (GET_REG(FLASH_SR) & FLASH_SR_BSY) {}

  rwmVal &= 0xFFFFFFFE;
  SET_REG(FLASH_CR, rwmVal);

  /* verify the write */
  if (*(volatile uint32 *)addr != word) {
    return false;
  }

  return true;
}

void flashLock() {
  /* take down the HSI oscillator? it may be in use elsewhere */

  /* ensure all FPEC functions disabled and lock the FPEC */
  SET_REG(FLASH_CR, 0x00000080);
}

void flashUnlock() {
  /* unlock the flash */
  SET_REG(FLASH_KEYR, FLASH_KEY1);
  SET_REG(FLASH_KEYR, FLASH_KEY2);
}

/* Minimum_Source*/

void setupFLASH() {
  /* configure the HSI oscillator */
  if ((pRCC->CR & 0x01) == 0x00) {
    uint32 rwmVal = pRCC->CR;
    rwmVal |= 0x01;
    pRCC->CR = rwmVal;
  }

  /* wait for it to come on */
  while ((pRCC->CR & 0x02) == 0x00) {}
}

bool writeChunk(uint32 *ptr, int size, const char *data)
{
  flashErasePage((uint32)(ptr));

  for (int i = 0; i < size; i = i + 4) {
    if (!flashWriteWord((uint32)(ptr++), *((uint32 *)(data + i)))) {
      return false;
    }
  }

  return true;
}

bool isNewBootloaderAlreadyInstalled()
{
  char *existingBootloader = (char *) BOOTLOADER_FLASH;
  int bootloaderSize=sizeof(maple_mini_boot20);
  
  for(int i=0;i<bootloaderSize;i++)
  {
    if (  maple_mini_boot20[i]!= *(existingBootloader+i))
    {
      return false;
    }
  }
  return true;
}

void setup() 
{
  char * bootloader = const_cast<char *>(maple_mini_boot20);
  int n = 0;
  bool alreadyInstalled = isNewBootloaderAlreadyInstalled();

  pinMode(BOARD_LED_PIN, OUTPUT);

  Serial.begin(9600);
  // Wait for the user to open the serial window.
  while (!(Serial.isConnected() && (Serial.getDTR() )))
  {
    digitalWrite(BOARD_LED_PIN, !digitalRead(BOARD_LED_PIN));
    delay(1000); // Slow blink
  }

  if (alreadyInstalled)
  {
    Serial.print("Congratulations. You have already updated to this version of the bootloader");
    while(1);
  }

  
  digitalWrite(BOARD_LED_PIN, LOW);
  Serial.println ("**************************************************************************************************");
  Serial.println ("*** This sketch will update the bootloader in the Maple Mini to the STM32duino bootloader     ****");
  Serial.println ("*** With this you can use up to 120KB of Flash and 20KB of RAM for a Sketch                   ****");
  Serial.println ("*** Uploading is also considerably faster on OSX (and possibly faster on Linux)               ****");
  Serial.println ("***                                                                                           ****");
  Serial.println ("***                      Only use with Maple mini boards                                      ****");
  Serial.println ("***                                                                                           ****");
  Serial.println ("*** WARNING. If the update fails your Maple mini may not have a functional bootloder.         ****");
  Serial.println ("***                                                                                           ****");
  Serial.println ("***                            YOU UPDATE AT YOUR OWN RISK                                    ****");
  Serial.println ("***                                                                                           ****");
  Serial.println ("***                                                                                           ****");
  Serial.println ("***                                                                                           ****");
  Serial.println ("***                                                                                           ****");
  Serial.println ("**************************************************************************************************");
  Serial.println ("***                                                                                           ****");
  Serial.println ("***                                                                                           ****");
  Serial.println ("***                         To confirm and proceed, enter Y                                   ****");
  Serial.println ("***                                                                                           ****");

  while (Serial.read() != 'Y')
  {
    delay(1);
  }

  Serial.println ("***                                                                                           ****");

  n = sizeof(maple_mini_boot20);

  setupFLASH();
  flashUnlock();

  int success = 1;
  int pages = n/PAGE_SIZE;
  int currentPage=1;
  for (int i = 0; i < n; i += PAGE_SIZE)
  {
    int size = 0;
    uint32* chunk = (uint32 *)(BOOTLOADER_FLASH + i);

    size = n - i;
    if (size > PAGE_SIZE)
    {
      size = PAGE_SIZE;
    }

    if (!writeChunk(chunk, size, &bootloader[i]))
    {
      Serial.println ();
      Serial.println ("WARNING, Update Failed!! The sketch will restart in 3 seconds and you can try to flash again");
      delay (3000);
      success = 0;
      break;
    }
    Serial.print("Writing flash page ");Serial.print(currentPage++);Serial.print(" of ");Serial.println(pages+1);
  }

  if (success)
  {
    flashLock();
    Serial.println ();
    Serial.println ("Update completed successfully. - Please test by uploading a different sketch");
    while (1) {
      digitalWrite(BOARD_LED_PIN, LOW);
      delay(500);
      digitalWrite(BOARD_LED_PIN, HIGH);
      delay(500);
    }
  }
}

void loop(){}
Sorry for my english.

User avatar
RogerClark
Posts: 5891
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: Maple Bootloader 2.0

Post by RogerClark » Wed Jul 01, 2015 12:07 pm

@tekk

The new bootloader has an additional upload mode that the old one didnt have.

The new mode (DFU Alt ID 2) uploads with the start address of 0x8002000
Where as the old bootloader only had one upload to flash location (DFU Alt ID 1) of 0x8005000

So if you try to use the bootloader 2 upload on an old bootloader, I suspect I will give an error, as it won't understand the upload mode ID.

The Old bootloader has upload to RAM, (DFU Alt ID 0), however this is effectively removed in the new bootloader because its virtually useless, as most sketches won't fit in the 20k ram on a Maple mini - and there were other technical reasons about the bootloader determining whether it had a valid sketch in RAM after soft reset, which make the upload to RAM problematic.

(The upload to RAM option was removed from the upload menu some time ago)

But for compatibility, DFU Alt ID 0 (upload to RAM) is retained in the new bootloader, it simply returns an error code if you try to use it (i.e by modifying platform.txt or some of the other core files)

Post Reply

Who is online

Users browsing this forum: No registered users and 2 guests